簡體   English   中英

c++ 轉換運算符重載失敗

[英]c++ conversion operator overloading fails

我有代碼為不同類型重載轉換運算符:

#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 class 中,可以使用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

因此,在您的情況下,當您使用復制構造時,沒有歧義,因為std::string不能使用 double 或 int 復制構造。 但是對於operator=它是模棱兩可的,因為您可以將整數分配給字符串並且編譯器不知道要使用哪個轉換運算符。 換句話說,編譯器可以為此使用您的字符串和 int 轉換運算符。

得到它的工作(感謝我的同事NB):

#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, typename std::enable_if<
           std::is_same<T, int>::value ||
           std::is_same<T, double>::value
           ,T>::type* = nullptr>
   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;
   s = o;

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

因此,必須為所有有效類型啟用模板。 但只要 (char) 在 std::enable_if<> 下的類型列表中,錯誤就會再次發生。 顯然 std::string= 運算符想要將 map 轉換為char (參見上面的第 4 項)。

我現在不明白的是為什么顯式指定 int() 和 double() 轉換運算符顯式不起作用

operator int() {
   return m_int;
}

operator double() {
   return m_double;
}

雖然這應該等同於

   template <typename T, typename std::enable_if<
           std::is_same<T, int>::value ||
           std::is_same<T, double>::value
           ,T>::type* = nullptr>
   operator T() {
      if (std::is_same<T, int>::value)
         return m_int;
      else
         return m_double;
   }

也不清楚為什么這不起作用:

template <typename T, typename std::enable_if<
        std::is_same<T, int>::value ||
        std::is_same<T, double>::value ||
        std::is_same<T, std::string>::value
        ,T>::type* = nullptr>
operator T() {
   if (std::is_same<T, std::string>::value)
      return m_string;
   else if (std::is_same<T, int>::value)
      return m_int;
   else
      return m_double;
}

也許有人可以給我一些見解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM