I tried two different ways to append an int
to a std::string
, and to my surprise, I got different results:
#include <string>
int main()
{
std::string s;
s += 2; // compiles correctly
s = s + 2; // compiler error
return 0;
}
Why does it compile and work correctly when I use the +=
operator, but fail when I use the +
operator?
I don't think the question is like How to concatenate a std::string and an int?
In that question,no answer uses +=
operator.And the difference between +=
and +
operator of std::string
is the key to solve my doubt.
Frankly,the question is a good example for explaining why c++ is so difficult to master.
s += 2;
is not doing what you think it's doing. It calls the overloaded+=
operator to achar
. It does not append the character'2'
, but rather the character with value 2, and the result will depend on the encoding used on your platform.There is no operator overload defined to allow
s + 2
to compile1. Hence the error.The solution in both cases is to use
std::to_string(2)
rather than theint
literal 2.1 Essentially the reason is because
operator+=
is not a template function, butstd::operator+
is, and overload resolution will favour a non-template function over a template one.TL;DR
operator+=
is a class member function inclass string
, whileoperator+
is a template function.The standard class
template<typename CharT> basic_string<CharT>
has overloaded functionbasic_string& operator+=(CharT)
, and string is justbasic_string<char>
.As values that fits in a lower type can be automatically cast into that type, in expression
s += 2
, the 2 is not treated asint
, butchar
instead. It has exactly the same effect ass += '\x02'
. A char with ASCII code 2 (STX) is appended, not the character '2' (with ASCII value 50, or 0x32).However, string does not have an overloaded member function like
string operator+(int)
,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:
For people concerned about why 2 isn't automatically cast to
char
withoperator+
,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 bothoperator+<char>
andoperator+<int>
, which is conflicting. For details, see Why isn't automatic downcasting applied to template functions?Meanwhile, the prototype of
operator+=
is:You see, no template here (it's a class member function), so the compiler deduces that type CharT is
char
from class implementation, andint(2)
is automatically cast intochar(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.
While @CoryKramer answer gives you the correct way to add an integer to a string, it doesn't explain why the instruction
s = s + 2
does not compile.The difference between the two instruction is that in the first one you use the
std::string
's += operator while in the second instruction, the compiler tries to cast2
to a string.There is no implicit conversion between
int
andstd::string
. however, you can cast anint
tochar
, so this is whys += 2
works.The correct way to add to your
string
would be