'Concatenate two string literals

I am reading Accelerated C++ by Koenig. He writes that "the new idea is that we can use + to concatenate a string and a string literal - or, for that matter, two strings (but not two string literals).

Fine, this makes sense I suppose. Now onto two separate exercises meant to illuminate this .

Are the following definitions valid?

const string hello = "Hello";

const string message = hello + ",world" + "!";

Now, I tried to execute the above and it worked! So I was happy.

Then I tried to do the next exercise;

const string exclam = "!";

const string message = "Hello" + ",world" + exclam;

This did not work. Now I understand it has something to do with the fact that you cannot concatenate two string literals, but I don't understand the semantic difference between why I managed to get the first example to work (isn't ",world" and "!" two string literals? Shouldn't this not have worked?) but not the second.



Solution 1:[1]

You should always pay attention to types.

Although they all seem like strings, "Hello" and ",world" are literals.

And in your example, exclam is a std::string object.

C++ has an operator overload that takes a std::string object and adds another string to it. When you concatenate a std::string object with a literal it will make the appropriate casting for the literal.

But if you try to concatenate two literals, the compiler won't be able to find an operator that takes two literals.

Solution 2:[2]

Your second example does not work because there is no operator + for two string literals. Note that a string literal is not of type string, but instead is of type const char *. Your second example will work if you revise it like this:

const string message = string("Hello") + ",world" + exclam;

Solution 3:[3]

Since C++14 you can use two real string literals:

const string hello = "Hello"s;

const string message = hello + ",world"s + "!"s;

or

const string exclam = "!"s;

const string message = "Hello"s + ",world"s + exclam;

Solution 4:[4]

The difference between a string (or to be precise, std::string) and a character literal is that for the latter there is no + operator defined. This is why the second example fails.

In the first case, the compiler can find a suitable operator+ with the first argument being a string and the second a character literal (const char*) so it used that. The result of that operation is again a string, so it repeats the same trick when adding "!" to it.

Solution 5:[5]

In case 1, because of order of operations you get:

(hello + ", world") + "!" which resolves to hello + "!" and finally to hello

In case 2, as James noted, you get:

("Hello" + ", world") + exclam which is the concat of 2 string literals.

Hope it's clear :)

Solution 6:[6]

if we write string s = "hello" + "world!"; RHS has following type const char [6] + const char [7]

Now both are built in data types. ie, they are not std::string types any more.

So, now operator overloading of built in types as defined by compiler applies. ie - no more operator + overloaded by std::string.

now let us turn to how compiler overloads

  • binary operator for two operands of const char * type.

it turns out, compiler did not overload for this case, as it is meaning less.

ie, adding two 'const char *' is semantically wrong as result would be another const char * in run time. There can be many reason why above does not make sense.

Hence over all, there is one generic rule for any operator overloading. it is : overloading any operator when all operands of that operator are built-in only. Compiler designers would take of such cases. In our exact question, std::string can't overload two 'const literals' because of this rule, and compiler choose to not to implement the + binary operator for its meaninglessness.

if we like the string literal form and we can a "s" operator as below. std::string p = "hello"s + "world!"s;

just suffix with s, the meaning changes. (s overloaded operator)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 DavidRR
Solution 2 DavidRR
Solution 3 Thomas Sablik
Solution 4 Péter Török
Solution 5 Stephen
Solution 6