Visual C++ - 显式调用基本类型的转换运算符

Log*_*uff 11 c++ operators visual-c++ visual-studio-2013

我正在玩一个类Foo,它定义了一个隐含的operator bool().我用作Foo多个函数的返回类型,因此我可以获得有关已完成的内容的信息,并调用Foo::operator bool()以获取操作是否已成功执行.

出于好奇,我还尝试在使用时明确调用转换运算符Foo:

if(!func().operator bool()) // func returned Foo
    throw std::logic_error("operation was not successful");
Run Code Online (Sandbox Code Playgroud)

这工作得很好.然后,我突然决定转储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;
}
Run Code Online (Sandbox Code Playgroud)

甚至智能感知也是正确的Error: expression must have a class type.所有这些都有解释吗?一个bug?(不需要的)扩展?它是什么?

Col*_*mbo 8

很好找!该标准肯定会使这个格式错误,需要诊断,[expr.ref]:

后缀表达式后跟一个点.或箭头->,可选地后跟关键字template(14.2),然后是id-expression,后缀表达式.[..] 对于第一个选项(点),第一个表达式应具有完整的类类型.

此外,不是一个扩展:将是一个无意义的扩展的地狱.似乎VC++实现bool了一些内部(类似类?)类型:

在Visual C++ 5.0及更高版本中,bool实现为内置类型,大小为1个字节.

该类型的类似语义显然没有被完全抑制.甚至

bool b;
b.operator std::string();
Run Code Online (Sandbox Code Playgroud)

编译(给出看似空的string),暗示内部类具有转换运算符模板.