私有库中的typecast运算符
typecast operator in private base
我在C++中发现了一些我认为奇怪的行为:私有基类中的类型转换运算符在试图解决隐式转换时会混淆编译器:
#include <iostream>
struct Base
{
#ifdef ENABLE
operator bool () const { return true; }
#endif
};
struct Derived : private Base
{
operator int () const { return 7; }
};
int main()
{
Derived o;
std::cout << o << 'n';
return 0;
}
如果没有-DENABLE
,代码编译得很好,并输出7
。有了-DENABLE
,代码就不再编译了,抱怨有一个不明确的重载。我尝试了gcc-4.6.5
、gcc-4.8.1
和clang-3.3
。令人困惑的是,我显然不能要求(bool)o
,因为Base
是私有基础。
这是预期的行为吗?
访问控制总是排在最后。标准报价:
10.2成员名称查找[class.Member.lookup]
1成员名称查找确定名称(id表达式)的含义在类范围内(3.3.7)。名称查找可能导致歧义,在在这种情况下程序是不正确的。对于id表达式,name查找从this的类范围开始;对于限定的id,name查找从nestedname-说明符的作用域开始名称查找发生在访问控制之前(3.4,第11条)。
8如果明确地找到了重载函数的名称,过载解决(13.3)也发生在访问控制之前歧义通常可以通过用类限定名称来解决名称
考虑这两个运算符的原因是:a)基类转换不会被派生类隐藏(如果两者都转换为同一类型,则会隐藏),b)bool
和int
都可以写入stdout,c)两者都不是更好的匹配,因此重载解析会产生歧义。这甚至在访问控制发挥作用之前就产生了一个硬错误。
相关文章:
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 私有库中的typecast运算符