我有重载不同类型的转换运算符的代码:

#include <string>
#include <iostream>

class MyClass {
   int m_int;
   double m_double;
   std::string m_string;

public:
   MyClass() : m_int{1}, m_double(1.2), m_string{"Test"} {};

   // overload the conversion operator for std::string
   operator std::string() {
      return m_string;
   }

   // overload the conversion operator for all other types
   template <typename T>
   operator T() {
      if (std::is_same<T, int>::value)
         return m_int;
      else
         return m_double;
   }
};

int main() {

   MyClass o;

   int i = o;
   double d = o;
   std::string s = o;

   std::cout << i << " " << " " << d << " " << s << std::endl;
}

这可以正常工作。但是当我尝试做
std::string s;
s = o;

编译失败
error: use of overloaded operator '=' is ambiguous (with operand types 'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') and 'MyClass')

显然,编译器实例化了一个不同于std::string()的转换运算符。如果删除模板部分,编译器将被迫使用std::string()转换运算符,并且它将再次运行。那我想念什么呢?

最佳答案

std::string类中,可以使用operator=()将字符(结果是整数)分配给std::string。这意味着以下代码是可接受的,因为operator=(char)确实存在:

std::string s1;

s1 = '1'; // works fine
s1 = 24; // works fine

但是您不能使用字符(以及整数)来复制构造字符串。
std::string s2  = '1'; // compilation fails
std::string s3 = 24;   // compilation fails

因此,在您的情况下,使用复制构造时不会有歧义,因为无法使用double或int复制std::string来构造operator=。但是对于ojit_code来说,它是模棱两可的,因为您可以将整数分配给字符串,并且编译器不知道要使用哪个转换运算符。换句话说,编译器可以同时使用字符串和int转换运算符。

关于c++ - C++转换运算符重载失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61204293/

10-11 08:31