【问题标题】:concatenating strings using "+" in c++ [duplicate]在c ++中使用“+”连接字符串[重复]
【发布时间】:2013-05-10 07:08:50
【问题描述】:

我是 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++。

【问题讨论】:

  • +std::string 重载(这就是第二个示例有效的原因)。第一个例子是尝试在两个字符串文字上使用+"Hello"", world" 不是std::string 对象)。
  • 下面的答案解释了为什么代码不起作用;我正在添加另一种修复代码的方法。您可以通过添加括号来更改操作顺序,以确保所有连接都调用std::string::operator+const std::string message = "Hello" + (", world" + exclam); 但在这种情况下,最好通过简单地去掉它们之间的 + 来连接文字。

标签: c++ string operators


【解决方案1】:

在第一个表达式中

"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 中,它通常不会在外部可见)。

其次,如果您有 other 库具有自己的字符串表示形式(例如,RogueWave 或 Qt 等 STL 之前的东西),它们同样有理由提供重载对于它们的字符串类型,编译器将无法在它们之间进行选择。

【讨论】:

  • 您是否尝试过实现std::string operator+(char const*, char const*) 重载?你可能是surprised ...
  • 哎呀,我写得太糟糕了,就一秒钟......
【解决方案2】:

这是因为"Hello" 在编译器读取时不是std::string,而是const char * - 这意味着您不能将它用于+

您可以使用以下方法轻松修复它:

 const std::string message = std::string("Hello") + ... 

【讨论】:

  • @0x499602D2: 输入错误的结果... ;)
【解决方案3】:

"Hello" 不是字符串,因为它不是std::string 类型的对象。它是一个字符串文字,它是一个字符数组。您不能将两个文字与 + 连接,但您可以将 std::string 与数组连接(反之亦然)。

"Hello" + ", world" + exclam 等价于("Hello" + ", world") + exclam,因此不起作用,因为它试图连接两个文字。但是,您可以在没有 + 运算符的情况下连接它们:"Hello" ", world" + exclam

hello + ", world" + "!"; 等价于(hello + ", world") + "!"。它将std::string 与文字连接起来;结果是一个新的std::string,然后与第二个文字连接。两种连接都是允许的。

原因是 C++ 是一个语言家族的成员,该语言家族在过去半个世纪左右的时间里缓慢发展,并且边缘仍然有古老语言的残余。

【讨论】:

    【解决方案4】:

    "Hello"", world" 在第一个示例中是 const char* 对象。由于指针的性质,没有定义将两个字符数组添加在一起的方法,尽管在逻辑上看起来不错。

    在第二个例子中,hello 是一个 std::string 对象,它定义了一个 + 运算符,以便在您编写时:

    hello + ", world"
    

    它会创建一个包含两个内容的新 std::string 对象。

    【讨论】:

      猜你喜欢
      • 2011-09-04
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2013-09-18
      • 2017-01-20
      相关资源
      最近更新 更多