class safe_bool_base {
protected:
void this_type_does_not_support_comparisons() const {}
};
template <typename T=void> class safe_bool : public safe_bool_base {
public:
void func() {
&safe_bool::this_type_does_not_support_comparisons;
&safe_bool_base::this_type_does_not_support_comparisons;
}
};
template<> class safe_bool<void> : public safe_bool_base {
public:
void func() {
&safe_bool::this_type_does_not_support_comparisons;
&safe_bool_base::this_type_does_not_support_comparisons;
}
};
错误讯息:
zzz.cpp: In member function 'void safe_bool<void>::func()':
zzz.cpp:7:10: error: 'void safe_bool_base::this_type_does_not_support_comparison
s() const' is protected
void this_type_does_not_support_comparisons() const {}
^
zzz.cpp:22:24: error: within this context
&safe_bool_base::this_type_does_not_support_comparisons;
^
我想知道为什么在模板专业化中无法访问受保护的成员。这些代码毫无意义,仅供测试。
答案 0 :(得分:1)
当公共从基类继承时,其受保护的成员将成为派生类&#39;保护成员,可以在派生类中访问&#39;成员职能。请注意,它们只能通过派生类本身(及其派生类)进行访问。但是不能通过基类访问受保护的成员。这就是为什么&safe_bool::this_type_does_not_support_comparisons;
有效,但&safe_bool_base::this_type_does_not_support_comparisons;
没有。
从标准$11.4/1 Protected member access [class.protected]:
开始(强调我的)
除了前面条款中描述的那些之外的附加访问检查 [class.access]在非静态数据成员或非静态时应用 member function是其命名类的受保护成员 ([class.access.base])114如前所述,访问受保护的 成员被授予,因为引用发生在朋友或成员中 一些C类。如果访问是形成指向成员的指针 ([expr.unary.op]),嵌套名称说明符应表示C或类 源自C。所有其他访问涉及(可能是隐含的) 对象表达式([expr.ref])。在这种情况下,对象的类 表达式应为C或从C派生的类。[例如:
class B { protected: int i; static int j; }; class D1 : public B { }; class D2 : public B { friend void fr(B*,D1*,D2*); void mem(B*,D1*); }; ... void D2::mem(B* pb, D1* p1) { pb->i = 1; // ill-formed p1->i = 2; // ill-formed i = 3; // OK (access through this) B::i = 4; // OK (access through this, qualification ignored) int B::* pmi_B = &B::i; // ill-formed int B::* pmi_B2 = &D2::i; // OK j = 5; // OK (because j refers to static member) B::j = 6; // OK (because B::j refers to static member) } ...
- 结束示例]
请注意标准中示例代码中的语句int B::* pmi_B = &B::i; // ill-formed
,基本上与代码的情况相同。顺便说一句,它与模板专业化无关。