For people new to template resolution and template type deduction in C++, they may have written this code and get confused why it doesn’t compile:
1
2
3
4
5
6
7
8
9
#include <string>
int main()
{
std::string s;
s += 2; // compiles correctly
s = s + 2; // compiler error
return 0;
}
And here’s my answer:
TL;DR operator+=() is a class member function in class string, while operator+() is a template function.
The standard class template<typename CharT> basic_string<CharT> has an overloaded member function basic_string& operator+=(CharT), and string is just basic_string<char>.
As values that fits in a shorter type can be interpreted as that type, in the expression s += 2, the 2 is not treated as int, but char instead. It has exactly the same effect as s += '\x02'. A char with ASCII code 2 (STX) is appended, instead of the character '2' (with ASCII value 50, or 0x32).
However, string does not have an overloaded member function like string operator+(int), so s + 2 is not a valid expression, thus throws an error during compilation. (More below)
You can use operator+ function in string in these ways:
1
2
3
s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only
For people concerned about why 2 isn’t automatically cast to char with operator+,
1
2
3
template <typename CharT>
basic_string<CharT>
operator+(const basic_string<CharT>& lhs, CharT rhs);
The above is the prototype[note] for the plus operator in s + 2, and because it’s a template function, it is requiring an implementation of both operator+<char> and operator+<int>, which is conflicting. For details, see Why isn’t automatic downcasting applied to template functions?
Meanwhile, the prototype of operator+= is:
1
2
3
4
5
template <typename CharT>
class basic_string{
basic_string&
operator+=(CharT _c);
};
You see, no template here (it’s a class member function), so the compiler deduces that type CharT is char from class implementation, and int(2) is automatically cast into char(2).
Note: Unnecessary code is stripped when copying from C++ standard include source. That includes typename 2 and 3 (Traits and Allocator) for template class “basic_string”, and unnecessary underscores, in order to improve readability.