2

I am a novice in C++ and i am referring Accelerated C++. While trying one of its exercise questions which says:

Are the following definitions valid? Why or why not?
const std::string exclam = "!";
const std::string message = "Hello" + ", world" + exclam;

When i tried & executed the program i am getting an error as:

invalid operands of types to binary operator +.

But the following code works perfectly fine:

const std::string hello = "Hello";
const std::string message = hello + ", world" + "!";

I am not clear with its execution! why this concatenation in the first case not working?

Thanks!I am using DEV C++.

poorvank
  • 7,524
  • 19
  • 60
  • 102
  • 2
    `+` is overloaded for `std::string` (which is why the second example works). The first example is trying to use `+` on two string literals (`"Hello"` and `", world"` are not `std::string` objects). – wkl May 15 '13 at 15:54
  • The answers below explain why the code doesn't work; I'm adding another way to fix the code. You can change the order of operations by adding parentheses that ensure `std::string::operator+` is called for all concatenations. `const std::string message = "Hello" + (", world" + exclam);` But in this case it is better to concatenate the literals by simply getting rid of the `+` in between them. – Praetorian May 15 '13 at 16:02

4 Answers4

7

In the first expression

"Hello" + ", world"

the compiler needs to find a suitable function such as operator+(const char *, const char *). No such function exists, so it cannot compile.

Conversely,

hello + ", world"

is looking for one matching operator+(const std::string&, const char*), and that overload does exist (it is provided by std::string).


Note that you even if you could write your own overload:

std::string operator+ (const char *left, const char *right)
{
    return std::string(left) + right;
}

(and you can't, as Praetorian points out) it wouldn't be a good idea.

Firstly, with primitive arguments, you'd lose ADL (ie, if the standard library put the operator in namespace std, it wouldn't normally be visible outside).

Secondly, if you have other libraries with their own string representations (eg. pre-STL stuff like RogueWave, or Qt, etc. etc.) they'd be equally justified in providing an overload for their string type, and the compiler would have no way to choose between them.

Useless
  • 64,155
  • 6
  • 88
  • 132
  • Have you tried implementing the `std::string operator+(char const*, char const*)` overload? You may be [surprised](http://www.parashift.com/c++-faq/cant-replace-ops-on-built-ins.html) ... – Praetorian May 15 '13 at 16:23
  • Doh, I wrote that terribly, just a sec ... – Useless May 15 '13 at 17:00
3

It's because "Hello" is not, when the compiler reads it, a std::string, but const char * - which means you can't use it for +.

You can trivial fix it with:

 const std::string message = std::string("Hello") + ... 
Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
1

"Hello" is not a string, in the sense that it's not an object of type std::string. It's a string literal, which is an array of characters. You can't concatenate two literals with +, but you can concatenate a std::string with an array (and vice versa).

"Hello" + ", world" + exclam is equivalent to ("Hello" + ", world") + exclam, and so doesn't work because it tries to concatenate two literals. However, you could concatenate them without the + operator: "Hello" ", world" + exclam

hello + ", world" + "!"; is equivalent to (hello + ", world") + "!". It concatenates a std::string with a literal; the result is a new std::string which is then concatenated with the second literal. Both concatenations are allowed.

The reason is that C++ is a member of a language family that has slowly evolved over the last half century or so, and still has vestigial remnants of ancient languages around the edges.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

"Hello" and ", world" in the first example are const char* objects. There is no defined way to add two character arrays together due to the nature of pointers, although logically it seems fine.

In the second example, hello is a std::string objects which has a + operator defined so that when you write:

hello + ", world"

it creates a new std::string object containing both pieces of content.

Ben Meier
  • 76
  • 4