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
std::string name = "Obama";
std::string str = "Hello " + name + " you are " + AGE + " years old!";
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."
Consider this:
std::string str = "Hello " + "world"; // bad!
Both the rhs and the lhs for operator + are char*s. There is no definition of operator + that takes two char*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:
std::string str = "Hello " + std::string("world"); // ok
There is a definition of operator + that takes a const char* as the lhs and a std::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:
std::string str = "Hello " + "there " + std::string("world"); // no good!
This doesn't work because you are trying to + two char*s before the lhs has been converted to std::string. But this is fine:
std::string str = std::string("Hello ") + "there " + "world"; // ok
Because once you've converted to std::string, you can + as many additional char*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:
((std::string("Hello ") + "there ") + "world");
((string + char*) + char*)
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:
((string) + char*)
Which is exactly what we just did, and which is still legal. But try the same thing with:
((char* + char*) + string)
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:
str += "Do you feel " + AGE + " years old?";
is converted to:
str += "Do you feel " + "42" + " years old?";
Which isn't valid since "Do you feel " and "42" are both const char[]. To solve this, you can make one a std::string, or just remove the +:
// 1.
str += std::string("Do you feel ") + AGE + " years old?";
// 2.
str += "Do you feel " AGE " years old?";
In line 2, there's a std::string involved (name). There are operations defined for char[] + std::string, std::string + char[], etc. "Hello " + name gives a std::string, which is added to " you are ", giving another string, etc.
In line 3, you're saying
char[] + char[] + char[]
and you can't just add arrays to each other.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With