Strings and C-strings
In C++, strings are usually represented as either std::string
or a C-string which has type char[N]
, where N
is the number of characters in the C-string plus one for the termination character (or null character) \0
.
When passing a string literal as, e.g., "Hello"
to a function, you are actually passing a char[6]
, which will decay into a pointer char*
, as C++ does not allow you to pass arrays by value. Additionally, C++ does not allow non-const pointers to string literals, and the parameter type must therefore become const char*
.
Concatenation
std::string
has existing overloads for the binary addition operator which allows you to concatenate two std::string
objects into one, as well as concatenate a std::string
object with a C-string.
std::string s1 = "Hello";
std::string s2 = "World";
// Uses 'std::string operator+(const std::string&, const std::string&)'.
std::string s3 = s1 + s2;
// Uses 'std::string operator+(const std::string&, const char*)'.
std::string s4 = s1 + "World";
// Also ok.
std::string s4 = "Hello" + s2;
There is however, no overload for concatenating two C-strings.
// Error. No overload for 'std::string operator+(const char*, const char*)' found.
std::string s5 = "Hello" + "World";
From left to right
Addition is performed left to right in C++, and hence, long concatenation expressions need to start with a std::string
object.
std::string s6 = "Hello" + ", " + s2; // Error. Addition is performed left-to-right and
// you can't concatenate two C-strings.
std::string s7 = s1 + ", " + "World"; // Ok. 's1 + ", "' returns a new temporary
// 'std::string' object that "World" is concat'ed to.
A simple solution
Using C++14 standard literals, you can create std::string
objects from literal expressions (note the trailing s
in the literal expression).
using namespace std::literals;
std::string s8 = "Hello"s + ", " + "World"; // Ok
Alternatively you can use the fact that the preprocessor will automatically concatenate literal strings separated with whitespace.
std::string s9 = "Hello" ", " "World"; // Ok
But then, you could just as well skip the whitespace altogether and use a single string literal.