Konkatenacja C ++; string + double; operator + vs operator + =

Sep 07 2020

gcc wersja 10.2.0, -std = c ++ 11

Nie próbuję konwertować podwójnej wartości na ciąg literału przy użyciu „std :: to_string ()”. Próba osiągnięcia podobnego efektu dodania liczby całkowitej do łańcucha, ale zamiast tego z podwójną wartością.

Oczekiwany wynik: „abcdA”

string s { "abcd" };
double d { 65.1 };
// s = s + d;    // Error. no match for ‘operator+’ (operand types are ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} and ‘double’)
s += d;

Obie metody „operator +” i „operator + =” klasy „string” mają wersję, która akceptuje argument „char”, ale tylko metoda „operator + =” wydaje się otrzymywać niejawnie przekonwertowaną wartość i nie powoduje błędu.

Dlaczego kompilator decyduje się na przekazanie przekonwertowanej wartości do jednej nad drugą.

Odpowiedzi

7 SebastianRedl Sep 07 2020 at 15:32

operator +=jest funkcją składową, a nie samym szablonem. Więc dla danego stringprzypadku jego argumentem RHS jest char. Kompilator będzie szukał konwersji na ten typ.

operator +to darmowy szablon funkcji, utworzony w taki sposób, aby działał z każdą basic_stringinstancją:

template<class CharT, class Traits, class Alloc>
std::basic_string<CharT,Traits,Alloc>
    operator+( const std::basic_string<CharT,Traits,Alloc>& lhs,
               CharT rhs );

Zauważ, że CharTjest używany zarówno w basic_stringargumencie, jak i jako RHS. Oznacza to, że kompilator spróbuje wydedukować to na podstawie obu argumentów i musi uzyskać spójny wynik. Ale dodatkowo lewa strona to a string, tworząc CharTa char, ale prawa strona to a double, tworząc CharTa double. Ta niespójność powoduje, że kompilator nie może wybrać typu dla, CharTa zatem całkowicie odrzuca przeciążenie. Następnie, kiedy skończy przeglądać wszystkie liczne przeciążenia operator +, poddaje się i mówi, że nie ma funkcji dopasowującej.