At the top of my file I have
#define AGE "42"
Later in the file I use ID multiple times including some lines that look like
1 std::string name = "Obama";
2 std::string str = "Hello " + name + " you are " + AGE + " years old!";
3 str += "Do you feel " + AGE + " years old?";
I get the error:
"error: invalid operands of types ‘const char [35]’ and ‘const char [2]’ to binary ‘operator+’"
on line 3. I did some research and found it was because of how C++ was treating the different strings and was able to fix it by changing "AGE" to "string(AGE)." However, I accidentally missed one of the instances until today and was wondering why the compiler wasn't complaining even though I still had an instance where it was just "AGE".
Through some trial and error I found that I only need string(AGE)
on lines where I don't concatenate another string that was created in the function body.
My questions is "what is going on in the background that C++ doesn't like concatenating a string with a string put there by the preprocessor unless you are also concatenating string that you defined in the function."
I had the same problem in my code. I was concatenating a string to create a string. Below is the part of code.
You cannot concatenate raw strings like this.
operator+
only works with twostd::string
objects or with onestd::string
and one raw string (on either side of the operation).The easiest solution is to turn your raw string into a
std::string
first:Of course, you should not use a macro in the first place. C++ is not C. Use
const
or, in C++11 with proper compiler support,constexpr
.Consider this:
Both the rhs and the lhs for
operator +
arechar*
s. There is no definition ofoperator +
that takes twochar*
s (in fact, the language doesn't permit you to write one). As a result, on my compiler this produces a "cannot add two pointers" error (yours apparently phrases things in terms of arrays, but it's the same problem).Now consider this:
There is a definition of
operator +
that takes aconst char*
as the lhs and astd::string
as the rhs, so now everyone is happy.You can extend this to as long a concatenation chain as you like. It can get messy, though. For example:
This doesn't work because you are trying to
+
twochar*
s before the lhs has been converted tostd::string
. But this is fine:Because once you've converted to
std::string
, you can+
as many additionalchar*
s as you want.If that's still confusing, it may help to add some brackets to highlight the associativity rules and then replace the variable names with their types:
The first step is to call
string operator+(string, char*)
, which is defined in the standard library. Replacing those two operands with their result gives:Which is exactly what we just did, and which is still legal. But try the same thing with:
And you're stuck, because the first operation tries to add two
char*
s.Moral of the story: If you want to be sure a concatenation chain will work, just make sure one of the first two arguments is explicitly of type
std::string
.AGE
is defined as"42"
so the line:is converted to:
Which isn't valid since
"Do you feel "
and"42"
are bothconst char[]
. To solve this, you can make one astd::string
, or just remove the+
:In line 2, there's a
std::string
involved (name
). There are operations defined forchar[] + std::string
,std::string + char[]
, etc."Hello " + name
gives astd::string
, which is added to" you are "
, giving another string, etc.In line 3, you're saying
and you can't just add arrays to each other.
In this particular case, an even simpler fix would be to just get rid of the "+" all together because AGE is a string literal and what comes before and after are also string literals. You could write line 3 as:
str += "Do you feel " AGE " years old?";
This is because most C/C++ compilers will concatenate string literals automatically. The above is equivalent to:
str += "Do you feel " "42" " years old?";
which the compiler will convert to:
str += "Do you feel 42 years old?";