将 int 附加到 std::string

Append int to std::string

我尝试了两种不同的方法来将 int 附加到 std::string,令我惊讶的是,我得到了不同的结果:

#include <string>

int main()
{
    std::string s;
    s += 2;     // compiles correctly
    s = s + 2;  // compiler error

    return 0;
}

为什么使用+=运算符编译正常,使用+运算符编译失败?

我觉得问题不像How to concatenate a std::string and an int?

在那个问题中,没有答案使用 += operator.And += 之间的区别 而 std::string+ 运算符是解决我疑惑的关键。

坦率地说,这个问题是解释为什么 c++ 如此难以掌握的一个很好的例子。

添加到 string 的正确方法是

std::string s;
s += std::to_string(2);
s = s + std::to_string(2);

s += 2; 并没有按照您的想法行事。它将重载的 += 运算符调用到 char。它不是附加字符'2',而是附加2的字符,结果将取决于您平台上使用的编码

没有定义运算符重载以允许 s + 2 编译 1。因此错误。

两种情况下的解决方案是使用 std::to_string(2) 而不是 int 文字 2.


1 本质上是因为 operator+= 不是模板函数,而 std::operator+ 是,重载解析将有利于非模板函数在模板上。

虽然@CoryKramer 的回答为您提供了将整数添加到字符串的正确方法,但并未解释指令 s = s + 2 无法编译的原因。

这两条指令的区别在于,在第一条指令中,您使用 std::string+= operator,而在第二条指令中,编译器尝试将 2 转换为字符串。

intstd::string 之间没有隐式转换。但是,您可以将 int 转换为 char,这就是 s += 2 有效的原因。

TL;DR operator+=class string中的class成员函数,而operator+是模板函数。

标准classtemplate<typename CharT> basic_string<CharT>重载了函数basic_string& operator+=(CharT),字符串就是basic_string<char>.

由于适合较低类型的值可以自动转换为该类型,因此在表达式 s += 2 中,2 而不是 被视为 int ,而是 char。它具有 s += '\x02' 完全相同的效果 。附加了 ASCII 代码 2 (STX) 的字符,不是字符“2”(ASCII 值为 50 或 0x32)。

但是string没有像string operator+(int)那样重载的成员函数,s + 2不是一个有效的表达式,因此会在编译时抛出错误。 (更多内容在下方)

您可以通过以下方式在字符串中使用 operator+ 函数:

s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only

对于关心为什么 2 不会自动转换为 charoperator+

的人
template <typename CharT>
  basic_string<CharT>
  operator+(const basic_string<CharT>& lhs, CharT rhs);

以上是s + 2中加号运算符的原型[注意],因为是模板函数,所以需要同时实现operator+<char>operator+<int>,这是冲突的。有关详细信息,请参阅

同时,operator+=的原型是:

template <typename CharT>
class basic_string{
    basic_string&
      operator+=(CharT _c);
};

你看,这里没有模板(它是一个 class 成员函数),因此编译器从 class 实现中推断出 CharT 类型是 char,并且 int(2)自动转换为 char(2)


注意:从 C++ 标准包含源复制时,不必要的代码被删除。这包括模板 class "basic_string" 的类型名称 2 和 3(特征和分配器)以及不必要的下划线,以提高可读性。