std::basic_...::operator+=(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

🌸 std::basic_string::operator+= β€” the glow-up operator 🌸

okay bestie, so this one's from the C++ Standard Libary (yes, that's how it's spelled on the page, we don't gatekeep typos here πŸ’…) β€” and it's genuinely one of the most iconic string moves ever. It's literally "add stuff to the end of my string" and it comes in five flavors. Five! Main character energy fr fr. ✨

✨ NAME ✨

std::basic_string::operator+= β€” it's std::basic_string::operator+=, no cap, that's the whole name πŸŽ€


πŸ¦‹ SYNOPSIS πŸ¦‹

   basic_string& operator+=( const basic_string& str );     (1)
(constexpr since C++20)
   basic_string& operator+=( CharT ch );                    (2)
(constexpr since C++20)
   basic_string& operator+=( const CharT* s );              (3)
(constexpr since C++20)
   basic_string& operator+=( std::initializer_list<CharT>   (4) (since C++11)
ilist );
(constexpr since C++20)
   template< class StringViewLike >                         (5) (since C++17)
   basic_string& operator+=( const StringViewLike& t );
(constexpr since C++20)

πŸ’– DESCRIPTION πŸ’–

The whole vibe: appends additional characters to the string. That's it, that's the tweet. 🫢

But bestie, each overload is a little different, so let's go one by one:

  1. Appends string str.
  2. Appends character ch.
  3. Appends the null-terminated character string pointed to by s.
  4. Appends characters in the initializer list ilist.
  5. Implicitly converts t to a string view sv as if by
std::basic_string_view<CharT,
   Traits> sv = t;

then appends characters in the string view sv as if by append(sv).

And listen β€” this overload is kinda picky about when it even shows up. It participates in overload resolution only if

std::is_convertible_v<const StringViewLike&,
                      std::basic_string_view<CharT, Traits>> is true

and

std::is_convertible_v<const StringViewLike&, const CharT*> is false.

Like, it needs to actually be convertible to a string view, but not convertible to a const CharT*. That's the vibe check it has to pass 😌


🌈 PARAMETERS 🌈

  • str β€” string to append
  • ch β€” character value to append
  • s β€” pointer to a null-terminated character string to append
  • ilist β€” std::initializer_list with the characters to append
  • t β€” object (convertible to std::basic_string_view) with the characters to append

πŸ‘‘ RETURN VALUE πŸ‘‘

It returns *this. Like, it just hands you back your own string so you can keep chaining. Obsessed. πŸ’«


⭐ COMPLEXITY ⭐

ngl, there are no standard complexity guarantees β€” the standard is out here saying "we don't promise anything." But typically, implementations behave similar to std::vector::insert(). So like, that's the usual vibe, not a promise 🫠


πŸ”₯ EXCEPTIONS πŸ”₯

If the operation would result in size() > max_size(), it throws std::length_error. (Dramatic, but fair.)

And if an exception is thrown for any reason, this function has no effect β€” that's the strong exception safety guarantee, bestie. It's giving "all or nothing." πŸ’€βœ¨


πŸŽ€ NOTES πŸŽ€

Overload (2) can accept any types that are implicitly convertible to CharT. For std::string, where CharT is char, the set of acceptable types includes all arithmetic types. This may have unintended effects. πŸ™ˆ Like, it's very eager. Watch out for that one.


🧚 EXAMPLE 🧚

// Run this code

#include <iomanip>
#include <iostream>
#include <string>

int main()
{
    std::string str;

    // reserve sufficient storage space to avoid memory reallocation
    str.reserve(50);

    std::cout << std::quoted(str) << '\n'; // empty string

    str += "This";
    std::cout << std::quoted(str) << '\n';

    str += std::string(" is ");
    std::cout << std::quoted(str) << '\n';

    str += 'a';
    std::cout << std::quoted(str) << '\n';

    str += {' ', 's', 't', 'r', 'i', 'n', 'g', '.'};
    std::cout << std::quoted(str) << '\n';

    str += 69.96; // Equivalent to str += static_cast<char>(69.96);
                  // 'E' (ASCII code 69) is appended by overload (2),
                  // which might not be the intent.

    // To add a numeric value, consider std::to_string():
    str += std::to_string(1729);

    std::cout << std::quoted(str) << '\n';
}

πŸ’œ Output:

""
"This"
"This is "
"This is a"
"This is a string."
"This is a string.E1729"

πŸ“ Defect reports πŸ“

The following behavior-changing defect reports were applied retroactively to previously published C++ standards. (Retroactive glow-ups, iconic behavior honestly.)

  • LWG 847 β€” Applied to: C++98. Behavior as published: there was no exception safety guarantee. Correct behavior: added strong exception safety guarantee.
  • LWG 2946 β€” Applied to: C++17. Behavior as published: overload (5) caused ambiguity in some cases. Correct behavior: avoided by making it a template.

🌸 See also 🌸

  • append β€” appends characters to the end (public member function)

πŸ’… friendly reminder bestie: overload (2) will absolutely eat your number and turn it into a char without asking. If you're trying to add a numeric value, that's a different conversation β€” see the example, it's doing the most with std::to_string().

okay that's the whole page!! πŸ¦‹ source & version & date realness: this came from http://cppreference.com, dated 2024.06.10, and the page is std::basic_...::operator+=(3). go forth and append, queen πŸ‘‘πŸ’–

πŸ“¦ where this page comes from