Append int to std::string

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 overloaded function basic_string& operator+=(CharT), and string is just basic_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 as int, but char instead. It has exactly the same effect as s += '\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:

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+,

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:

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.

Leave a Comment