Visual Studio无法在布尔运算的上下文中实例化转换(转换)运算符模板(T = bool)

时间:2012-11-17 20:53:00

标签: c++ visual-studio-2010 visual-c++ c++11 visual-studio-2012

为什么Visual Studio 2010和Visual Studio 2012无法编译此代码?

Codepad.org,Xcode,gcc,LLVM,Clang都没有问题但是Visual Studio却在床上大踏步走:

struct S {
  template <class T> inline operator T () const { return T (); }
};
int main () {
  // NOTE: "S()" denotes construction in these examples
  struct F {
    void operator() (bool) { }
    static void toint (int) { }
    static void tostr (char const*) { }
  };
  bool b1 = S (); // Okay
  bool b2 (S ()); // Okay
  F () (S ());    // Okay
  F::toint (S ());// Okay
  F::tostr (S ());// Okay

  S () || false;  // Error: error C2676: binary '||' : 'vf::S' does
                  // not define this operator or a conversion to a type
                  // acceptable to the predefined operator
  return 0;
}

添加explicit关键字不会改变gcc或clang的内容。产生的错误消息是:

error C2676: binary '||' : 'S' does not define this operator or a
  conversion to a type acceptable to the predefined operator

2 个答案:

答案 0 :(得分:3)

这是一个错误,至少在C ++ 03中(不确定C ++ 11)。

根据C ++03§13.3.1.2中的重载决策规则,选择了内置||运算符,因为没有为{{1}定义用户定义的||运算符}。

§5.15/ 1说:

  

S运算符组从左到右。操作数都隐式转换为||(第4节)。 [...]

§12.3/ 2说:

  

用户定义的转换仅在明确无误的情况下应用(10.2,12.3.2)。 [...]

§12.3/ 5:

  

只有在明确无误的情况下,才会隐式使用用户定义的转换。 [...]函数重载决策(13.3.3)选择最佳转换函数来执行转换。

§13.3.2/ 3:

  

其次,要使bool成为可行的函数,每个参数都应存在一个隐式转换序列(13.3.3.1),它将该参数转换为F的相应参数。

显然F定义了用户定义的S转换。内置的bool运算符是重载决策的可行函数,因为它是唯一的运算符,所以它是最好的。所以表达形式很好。

同样值得注意的是§4/ 3,其中说:

  

当且仅当声明“||”格式正确时,表达式e可以隐式转换为类型T,对于某些发明的临时变量T t=e; (8.5)。 [...]

所以我很好奇Visual Studio是否也为语句t生成错误。

答案 1 :(得分:0)

如果你将隐式类型转换为布尔值,编译器必须检查是否有运算符||定义哪个采用布尔值。这是(希望!)没有定义,因为它会打破捷径。所以他必须检查是否有一个转换运算符定义为它提供了为全局|| -operator定义的东西。你可以通过向bool,BOOL或int添加转换运算符来解决这个问题(无论如何都是^^)......?

operator bool() {return this != null && this != 0xcccccccc;}

这个BTW只是一个黑客,提供一个逻辑上有意义的转换会更好。

我确实在调试模式下有一个为0xcccccccc标记未初始化内存的常量,但我不知道。