我的文件顶部有
#define AGE "42"
稍后在文件中我多次使用ID,包括一些看起来像
的行1 std::string name = "Obama";
2 std::string str = "Hello " + name + " you are " + AGE + " years old!";
3 str += "Do you feel " + AGE + " years old?";
我收到错误:
“错误:类型'const char [35]'和'const char [2]'到二元'运算符+'的无效操作数”
第3行。我做了一些研究,发现这是因为C ++如何处理不同的字符串并且能够通过将“AGE”更改为“string(AGE)”来修复它。但是,直到今天我才意外地错过了其中一个实例,并且想知道为什么编译器没有抱怨,即使我还有一个只是“AGE”的实例。
通过一些试验和错误,我发现我只需要string(AGE)
行,我不会连接在函数体中创建的另一个字符串。
我的问题是“在后台发生的事情,C ++不喜欢将字符串与预处理器放置的字符串连接起来,除非你还连接了你在函数中定义的字符串。”
答案 0 :(得分:73)
考虑一下:
std::string str = "Hello " + "world"; // bad!
operator +
的rhs和lhs都是char*
s。没有operator +
的定义需要两个char*
(实际上,该语言不允许您编写一个)。结果,在我的编译器上产生一个"不能添加两个指针"错误(你的表面上显然是用数组来表达的,但它也是同样的问题)。
现在考虑一下:
std::string str = "Hello " + std::string("world"); // ok
是 operator +
的定义,其中const char*
为lhs,std::string
为rhs,所以现在每个人都很高兴。
您可以根据需要将此扩展到连接链。但它可能会变得混乱。例如:
std::string str = "Hello " + "there " + std::string("world"); // no good!
这不起作用,因为您在将lhs转换为+
之前尝试char*
两个std::string
。但这很好:
std::string str = std::string("Hello ") + "there " + "world"; // ok
因为一旦您转换为std::string
,就可以+
尽可能多地添加char*
个。{/ p>
如果这仍然令人困惑,可能有助于添加一些括号以突出显示关联性规则,然后将变量名称替换为其类型:
((std::string("Hello ") + "there ") + "world");
((string + char*) + char*)
第一步是调用标准库中定义的string operator+(string, char*)
。用它们的结果替换这两个操作数给出:
((string) + char*)
这正是我们刚刚做的,哪些仍然合法。但尝试同样的事情:
((char* + char*) + string)
你被卡住了,因为第一个操作试图添加两个char*
。
故事的道德:如果你想确定连接链是否有效,只需确保前两个参数中的一个显式为std::string
类型。
答案 1 :(得分:9)
AGE
定义为"42"
所以行:
str += "Do you feel " + AGE + " years old?";
转换为:
str += "Do you feel " + "42" + " years old?";
由于"Do you feel "
和"42"
都是const char[]
,因此无效。要解决此问题,您可以将其设为std::string
,或者只删除+
:
// 1.
str += std::string("Do you feel ") + AGE + " years old?";
// 2.
str += "Do you feel " AGE " years old?";
答案 2 :(得分:4)
在第2行中,涉及std::string
(name
)。为char[] + std::string
,std::string + char[]
等定义了操作。"Hello " + name
提供std::string
,添加到" you are "
,提供另一个字符串等。
在第3行,你说的是
char[] + char[] + char[]
你不能只是互相添加数组。
答案 3 :(得分:4)
你不能像这样连接原始字符串。 operator+
仅适用于两个std::string
个对象或一个std::string
和一个原始字符串(位于操作的任一侧)。
std::string s("...");
s + s; // OK
s + "x"; // OK
"x" + s; // OK
"x" + "x" // error
最简单的解决方案是首先将原始字符串转换为std::string
:
"Do you feel " + std::string(AGE) + " years old?";
当然,您不应该首先使用宏。 C ++不是C.使用const
或者在C ++ 11中使用适当的编译器支持constexpr
。
答案 4 :(得分:1)
在这种特殊情况下,一个更简单的解决办法是一起消除所有的“ +”,因为AGE是字符串文字,而前后都是字符串文字。您可以将第3行写为:
str += "Do you feel " AGE " years old?";
这是因为大多数C / C ++编译器都会自动连接字符串文字。以上等同于:
str += "Do you feel " "42" " years old?";
编译器将转换为:
str += "Do you feel 42 years old?";
答案 5 :(得分:0)
我的代码中遇到了同样的问题。我正在连接一个字符串来创建一个字符串。以下是代码的一部分。
int scannerId = 1;
std:strring testValue;
strInXml = std::string(std::string("<inArgs>" \
"<scannerID>" + scannerId) + std::string("</scannerID>" \
"<cmdArgs>" \
"<arg-string>" + testValue) + "</arg-string>" \
"<arg-bool>FALSE</arg-bool>" \
"<arg-bool>FALSE</arg-bool>" \
"</cmdArgs>"\
"</inArgs>");