gpt4 book ai didi

c++ - 奇怪的编译器错误和模板继承

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:08:56 26 4
gpt4 key购买 nike

谁能解释一下为什么这段代码:

class safe_bool_base
{ //13
protected:

typedef void (safe_bool_base::*bool_type)() const;

void this_type_does_not_support_comparisons() const {} //18

safe_bool_base() {}
safe_bool_base(const safe_bool_base&) {}
safe_bool_base& operator=(const safe_bool_base&) { return *this; }
~safe_bool_base() {}
};

template <typename T=void> class safe_bool : public safe_bool_base
{
public:

operator bool_type() const
{
return (static_cast<const T*>(this))->boolean_test() ? &safe_bool_base::this_type_does_not_support_comparisons : 0;
}

protected:

~safe_bool() {}
};

template <> class safe_bool<void> : public safe_bool_base
{
public:

operator bool_type() const
{
return (boolean_test() == true) ? &safe_bool_base::this_type_does_not_support_comparisons : 0; //46
}

protected:

virtual bool boolean_test() const = 0;
virtual ~safe_bool() {}
};

产生以下编译器错误?

c:\project\include\safe_bool.hpp(46) : error C2248: 'safe_bool_base::this_type_does_not_support_comparisons' : cannot access protected member declared in class 'safe_bool_base'
c:\project\include\safe_bool.hpp(18) : see declaration of 'safe_bool_base::this_type_does_not_support_comparisons'
c:\project\include\safe_bool.hpp(13) : see declaration of 'safe_bool_base'

由于 safe_bool 模板都派生自 safe_bool_base,我不明白为什么不能访问基类的 protected 成员。

我错过了什么吗?

最佳答案

这可能会有所帮助(在非模板情况下也可重现)

struct A{
protected:
void f(){}
};

struct B : A{
void g(){&A::f;} // error, due to Standard rule quoted below
};

int main(){
}

VS gives "'A::f' : cannot access protected member declared in class 'A'"

对于相同的代码,Comeau 给出

"ComeauTest.c", line 7: error: protected function "A::f" (declared at line 3) is not accessible through a "A" pointer or object void g(){&A::f;} ^

"ComeauTest.c", line 7: warning: expression has no effect void g(){&A::f;}

这是实现预期意图的固定代码

struct A{
protected:
void f(){}
};

struct B : A{
void g(){&B::f;} // works now
};

int main(){
}

那么,为什么第一个代码片段不起作用?

这是因为C++ Standard03中的如下规则

11.5/1- "When a friend or a member function of a derived class references a protected nonstatic member function or protected nonstatic data member of a base class, an access check applies in addition to those described earlier in clause 11.102) Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class) (5.2.5). If the access is to form a pointer to member, the nested-name-specifier shall name the derived class (or any class derived from that class).

所以改变运算符函数内的返回值如下

return (boolean_test() == true) ? &safe_bool<void>::this_type_does_not_support_comparisons : 0; //46 

return (static_cast<const T*>(this))->boolean_test() ? &typename safe_bool<T>::this_type_does_not_support_comparisons : 0;

编辑 2:请忽略我的解释。大卫是对的。归结为以下内容。

struct A{
protected:
int x;
};

struct B : A{
void f();
};

struct C : B{};

struct D: A{ // not from 'C'
};

void B::f(){
x = 2; // it's own 'A' subobjects 'x'. Well-formed

B b;
b.x = 2; // access through B, well-formed

C c;
c.x = 2; // access in 'B' using 'C' which is derived from 'B', well-formed.

D d;
d.x = 2; // ill-formed. 'B' and 'D' unrelated even though 'A' is a common base
}

int main(){}

关于c++ - 奇怪的编译器错误和模板继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3657494/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com