我正在玩一个类Foo
,它定义了一个隐含的operator bool()
。我使用Foo
作为多个函数的返回类型,因此我可以获得有关已执行操作的信息并调用Foo::operator bool()
以获取操作是否已成功执行。
出于好奇,我还在使用Foo
时尝试显式调用转化运算符:
if(!func().operator bool()) // func returned Foo
throw std::logic_error("operation was not successful");
工作得很好。然后,我突然决定转储Foo
类并使用简单的bool
,但我忘记删除函数返回值的.operator bool()
调用。所以我发现了一组Visual C ++ 12.0编译器(Visual Studio 2013)的奇怪行为。
转换运算符到bool
的显式调用都不会在GCC中有效:
request for member ‘operator bool’ in ‘true’, which is of non-class type ‘bool’
现在,我使用Visual Studio获得的行为:
#include <iostream>
using std::cout;
using std::endl;
bool func()
{
return true;
}
int main()
{
bool b = true.operator bool();
cout << b << endl; // error C4700: uninitialized local variable 'b' used
// evaluates to true (probably like b would do if it compiled)
if(false.operator bool())
cout << "a" << endl;
cout << func().operator bool() << endl; // prints nothing
int m = 10;
cout << m.operator int() << endl; // prints nothing
// correctly gives error: left of '.<' must have class/struct/union
cout << m.operator <(10) << endl;
}
即使是智能感知也是正确的,并显示Error: expression must have a class type
。
所有这些都有解释吗?一个bug? (不需要的)扩展?它是什么?
答案 0 :(得分:8)
后缀表达式,后跟点
.
或箭头->
, 可选地后跟关键字template
(14.2),然后 后跟一个 id-expression ,是一个后缀表达式。 [..] For 第一个选项(点)第一个表达式应具有完整的类 类型。强>
此外,不是一个扩展:将是一个荒谬的扩展的地狱。似乎VC ++使用internal (class-like?) type:
来实现bool
在Visual C ++ 5.0及更高版本中,
bool
是作为内置类型实现的 大小为1个字节。
该类型的类似语义显然没有被完全抑制。甚至
bool b;
b.operator std::string();
编译(giving a seemingly empty string
),暗示内部类具有转换运算符模板。