我是C ++的新手,我指的是Accelerated C ++。在尝试其中一个练习题时说:
Are the following definitions valid? Why or why not?
const std::string exclam = "!";
const std::string message = "Hello" + ", world" + exclam;
当我试过&执行程序我得到一个错误:
类型为二元运算符的无效操作数+。
但是下面的代码非常合适:
const std::string hello = "Hello";
const std::string message = hello + ", world" + "!";
我不清楚它的执行情况!为什么第一种情况下的这种连接不起作用?
谢谢!我正在使用DEV C ++。
答案 0 :(得分:7)
在第一个表达式
中"Hello" + ", world"
编译器需要找到合适的函数,例如operator+(const char *, const char *)
。
没有这样的函数,因此无法编译。
相反,
hello + ", world"
正在寻找一个匹配的operator+(const std::string&, const char*)
,而 的重载确实存在(由std::string
提供)。
请注意,即使您可以编写自己的重载:
std::string operator+ (const char *left, const char *right)
{
return std::string(left) + right;
}
(你不能,正如Praetorian指出的那样)这不是一个好主意。
首先,使用原始参数,您将失去ADL(即,如果标准库将运算符放在名称空间std
中,则通常不会在外部显示)。
其次,如果你有其他库有他们自己的字符串表示(例如,像RogueWave之前的STL之类的东西,或Qt等等),他们在提供过载方面同样合理对于他们的字符串类型,编译器无法在它们之间进行选择。
答案 1 :(得分:3)
这是因为"Hello"
在编译器读取时不是std::string
,而是const char *
- 这意味着你不能将它用于+
。
您可以通过以下方式轻松修复它:
const std::string message = std::string("Hello") + ...
答案 2 :(得分:1)
"Hello"
不是字符串,因为它不是std::string
类型的对象。它是一个字符串文字,它是一个字符数组。您不能将两个文字与+
连接起来,但可以将std::string
与数组连接(反之亦然)。
"Hello" + ", world" + exclam
等同于("Hello" + ", world") + exclam
,因此无法工作,因为它会尝试连接两个文字。但是,您可以在没有+
运算符的情况下连接它们:"Hello" ", world" + exclam
hello + ", world" + "!";
相当于(hello + ", world") + "!"
。它将std::string
与文字连接起来;结果是一个新的std::string
,然后与第二个文字连接。两个连接都是允许的。
原因在于C ++是一个语言家族的成员,在过去的半个世纪左右的时间里,它已经慢慢进化,并且仍然有古老语言的残余遗迹。
答案 3 :(得分:0)
"Hello"
和", world"
是const char *对象。由于指针的性质,没有定义的方法将两个字符数组添加到一起,尽管从逻辑上看似乎很好。
在第二个例子中,hello是一个std :: string对象,它定义了一个+运算符,以便在你写时:
hello + ", world"
它创建一个包含两段内容的新std :: string对象。