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

时间:2015-04-22 08:29:17

标签: c++ visual-c++ visual-studio-2013 operators

我正在玩一个类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? (不需要的)扩展?它是什么?

1 个答案:

答案 0 :(得分:8)

好的发现!该标准肯定会使这种格式错误,需要诊断,[expr.ref]:

  

后缀表达式,后跟点.或箭头->,   可选地后跟关键字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),暗示内部类具有转换运算符模板。