1

考虑以下程序,它编译并运行良好:

#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
}

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

int main()
{
  BB b;
  string s;
  s = b;
} 

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

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

为什么这个调用是模棱两可的?这背后的原因是什么?看起来有很多重载,operator=例如一个 for char,一个 for char*,一个 forconst char*等。这就是上面的程序使编译器变得模棱两可。

4

2 回答 2

5

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

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

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

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

于 2015-10-29T14:47:45.413 回答
2

你调用operator =,但如果它是一个常规函数,它会是一样的:

void f(int x);
void f(const string &y);

int main() {
    BB b;
    f(b);
    return 0;
}

由于BB可以转换为intor string,因此编译器不知道f要调用哪个函数。

您的第一个示例有效的唯一原因是复制构造函数在那里被调用,它只const string&作为一个参数,所以没有多项选择。

于 2015-10-29T14:47:09.187 回答