我的代码中出现复制/粘贴错误,并以如下一行结尾:
myString = otherString; + "?" + anotherString;
第一个分号后的代码未发出任何错误或警告。使用online compiler仔细检查我的环境,我创建了这个快速示例,该示例也可以编译并运行:
int main()
{
std::string sText("Hello World");
std::string sMore(" again");
+ "???" + sText + sMore; //No warning, no error
cout << sText; //output "Hello World" as expected
+ 4; //Warning has no effect
+ sMore; //error: no match for ‘operator+’ (operand type is ‘std::string {aka std::basic_string}’)
return 0;
}
那么开始+在做什么?
答案 0 :(得分:4)
文字字符串(例如"???"
)实际上是字符数组。像所有其他数组一样,它们衰减到指向自己的指针。这就是这里发生的情况,表达式+ "???"
在指向字符串第一个元素的指针上应用一元+
一元运算符。
这将导致另一个(指向一个字符的)指针等于第一个指针,然后可以将其用于添加到std::string
个对象中。
其他文字(例如数字)也会发生同样的情况,这就是+4
也有效的原因。
但是没有为+
定义一元std::string
运算符,这就是为什么您收到+sMore
的错误的原因。
答案 1 :(得分:2)
首先,字符串文字是字符数组。当您将数组作为操作数传递给一元运算符+时,该数组将隐式转换为指向第一个元素(类型为const char
)的指针。这种隐式转换称为衰减。
一元运算符+的结果是转换后的操作数,即在这种情况下为字符串文字第一个元素的指针。
以下二进制运算符+调用重载运算符,该运算符将指向字符的指针作为一个操作数,将std::string
对象作为另一个操作数。
对于整数,运算符+的行为相同,除了整数对整数的衰减,而不是数组到指针的衰减。 int
不会升级,但是所有小于int
的类型都会被提升。对于std::string
,一元+没有重载,因此会出现错误。
我认为在那条线上没有警告,因为即使没有存储值,调用operator +也会“有效果”。
缺少效果只是警告如果操作结果被丢弃的原因。在字符串情况下,结果用作二进制运算符的操作数,因此没有理由警告无效。
现在,二进制运算的结果被散布了,也没有任何效果,但是编译器几乎不可能分析所有可能的代码路径的“效果”,并且也没有尝试这样做。编译器足够友好,可以检查指针上的原始操作,但它可能不会打扰分析函数调用(类的操作符重载是函数)。