奇怪的编译器错误和模板继承
有人可以解释一下为什么这段代码:
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
,我不明白为什么无法访问基类的受保护成员。
我错过了什么吗?
Could someone explain me why this code:
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() {}
};
Produces the following compiler error ?
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'
Since both safe_bool
templates derive from safe_bool_base
, I don't understand why one can't access a protected member of the base class.
Am I missing something ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Chubsdad 的回答澄清了您的问题:为什么模板专业化会出现错误。
现在以下 C++ 标准规则
14.7.2/11 通常的访问检查规则不适用于用于指定显式的名称
实例化。 [注意:特别是函数中使用的模板参数和名称
声明符(包括参数类型、返回类型和异常规范)可能是
通常无法访问的私有类型或对象,并且模板可能是
通常无法访问的成员模板或成员函数。 - 尾注]
将解释为什么通用模板实例化不会抛出错误。即使您有私有访问说明符,它也不会抛出异常。
Chubsdad's answer clarifies your question of why there's an error for the template specialization.
Now the following C++ standard rule
14.7.2/11 The usual access checking rules do not apply to names used to specify explicit
instantiations. [Note: In particular, the template arguments and names used in the function
declarator (including parameter types, return types and exception specifications) may be
private types or objects which would normally not be accessible and the template may be a
member template or member function which would not normally be accessible. — endnote]
would explain why the generic template instantiation wouldn't throw an error. It will not throw even if you have private access specifier.
我不认为这与模板有任何关系。您的示例代码可以简化为这样,但它仍然会给出等效的错误:
我相信问题是您无法将成员函数指针返回到公共接口中的受保护成员。(编辑:不正确...)I don't think this is anything to do with templates. Your example code can be reduced to this, and it still gives the equivalent error:
I believe the issue is you can't return member-function pointers to protected members in the public interface.(Edit: not true...)这可能会有所帮助(也可以在非模板情况下重现)
对于相同的代码,科莫给出
这是实现预期意图的固定代码
那么,为什么第一个代码片段不起作用?
这是因为 C++ Standard03 中的以下规则
因此,更改运算符函数内的返回值,如下所示
编辑 2:请忽略我的解释。大卫是对的。这就是它的归结。
This should probably help (reproducible in a non template situation also)
For the same code, Comeau gives
Here is the fixed code which achieves the desired intentions
So, why does the first code snippet not work?
This is because of the following rule in the C++ Standard03
So change the return within operator functions as follows
EDIT 2: Please ignore my explanations. David is right. Here is what it boils down to.