错误: 类型为‘ const char [35]’和‘ const char [2]’的操作数对二进制‘运算符 +’无效

在我档案的最上面

#define AGE "42"

在后面的文件中,我多次使用 ID,其中一些行看起来像

std::string name = "Obama";
std::string str = "Hello " + name + " you are " + AGE + " years old!";
str += "Do you feel " + AGE + " years old?";

我得到了一个错误:

错误: 类型为‘ const char [35]’和‘ const char [2]’的操作数对二进制‘运算符 +’无效

在3号线。我做了一些研究,发现这是因为 C + + 处理不同字符串的方式,并且能够通过将“ AGE”改为“ string (AGE)”来修复它然而,直到今天我才意外地错过了一个实例,我想知道为什么编译器不抱怨,即使我仍然有一个实例,它只是“ AGE”。

通过一些尝试和错误,我发现我只需要在不连接在函数体中创建的另一个字符串的行上使用 string(AGE)

我的问题是“在后台发生了什么,C + + 不喜欢连接字符串和预处理器放在那里的字符串,除非你也连接在函数中定义的字符串。”

173706 次浏览

想想这个:

std::string str = "Hello " + "world"; // bad!

operator +的 rhs 和 lhs 都是 char*。没有 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!

这是不工作的,因为您正在尝试 +两个 char*之前,lhs 已经转换为 std::string。但这没关系:

std::string str = std::string("Hello ") + "there " + "world"; // ok

因为一旦你转换到 std::string,你可以 +多少额外的 char*作为你想要的。

如果这仍然让人困惑,可以添加一些括号来突出显示关联性规则,然后用它们的类型替换变量名:

((std::string("Hello ") + "there ") + "world");
((string + char*) + char*)

第一步是调用 string operator+(string, char*),它是在标准库中定义的。将这两个操作数用它们的结果替换为:

((string) + char*)

这正是我们刚刚所做的,这仍然是合法的。但试试同样的事情:

((char* + char*) + string)

然后您就卡住了,因为第一个操作尝试添加两个 char*

这个故事的寓意是: 如果您想确保连接链能够正常工作,只需要确保前两个参数中的一个是显式的 std::string类型。

在第2行中,涉及到一个 std::string(name)。有为 char[] + std::stringstd::string + char[]等定义的操作。"Hello " + name给出一个 std::string,它被添加到 " you are ",给出另一个字符串,等等。

在第三行,你是说

char[] + char[] + char[]

你不能只是相互添加数组。

您不能像这样连接原始字符串。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

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?";

我的代码也有同样的问题。我在连接一个字符串来创建一个字符串。下面是代码的一部分。

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>");

在这个特殊的例子中,一个更简单的解决方案是将“ +”全部去掉,因为 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?";