为什么这个赋值操作导致函数调用不明确?

Des*_*tor 1 c++ function-call ambiguous-call assignment-operator

考虑以下程序编译并运行正常:

#include <iostream>
#include <string>
using std::string;
struct BB
{
 // generic cast
 template<typename T>
 operator T() const
 {   
   std::cout<<"Generic cast\n";
   return 0;
 }
 // string cast
 operator string() const
 { 
   std::cout<<"string cast\n";
   return string("hello");
 }
};
int main()
{
  BB b;
  string s = b; // copy constructor
}
Run Code Online (Sandbox Code Playgroud)

但如果我稍微更改main()函数的代码如下:

int main()
{
  BB b;
  string s;
  s = b;
} 
Run Code Online (Sandbox Code Playgroud)

编译器给出以下错误消息(请参阅此处的实时演示)

[Error] ambiguous overload for 'operator=' (operand types are 'std::string {aka std::basic_string<char>}' and 'BB')
Run Code Online (Sandbox Code Playgroud)

为什么这个电话不明确?这背后的原因是什么?看起来有很多重载operator=像一个for char,one for char*,one for const char*etc.这就是上面的程序让编译器变得模棱两可.

Nat*_*ica 5

您的问题是模板转换运算符.

template<typename T>
operator T() const
{
    std::cout << "Generic cast\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

允许BB转换为任何内容.因此,std::string::operator=可以考虑采用不同类型的所有重载.由于它们都是有效的,因此无法解决歧义并且您会收到错误.

如果您删除了模板转换,那么它将进行编译.模板转换也可以标记为explicit,然后您可以使用a static_cast到您想要的类型.

  • 如果你进行模板化转换`explicit`,它也会编译.`explicit`有一个缺点,你需要一个`static_cast`,但是对于转换运算符来说,显式可能是一个好主意. (3认同)
  • @Niall谢谢你.把它添加到答案中. (2认同)