将int追加到std :: string

nav*_*ver 38 c++ stdstring

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

#include <string>

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么我在使用+=运算符时编译并正常工作,但在使用+运算符时失败?

我不认为问题是如何连接std :: string和int?

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

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

iBu*_*Bug 48

TL; DR operator+=是类成员函数class string,同时operator+是模板函数.

标准类template<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 + function:

s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only
Run Code Online (Sandbox Code Playgroud)

对于关注为什么2不会被自动转换char为的人operator+,

template <typename CharT>
  basic_string<CharT>
  operator+(const basic_string<CharT>& lhs, CharT rhs);
Run Code Online (Sandbox Code Playgroud)

以上是原型[注]为加运营商s + 2,因为它是一个模板函数,它同时需要的实现operator+<char>operator+<int>,这是相互矛盾的.有关详细信息,请参阅为什么不将自动向下转换应用于模板函数?

同时,原型operator+=是:

template <typename CharT>
class basic_string{
    basic_string&
      operator+=(CharT _c);
};
Run Code Online (Sandbox Code Playgroud)

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


注意:从C++标准包含源复制时,将删除不必要的代码.其中包括模板类"basic_string"的typename 2和3(Traits和Allocator),以及不必要的下划线,以提高可读性.


Bat*_*eba 43

s += 2;没有做你认为它正在做的事情.它将重载+=运算符调用到a char.它并没有追加字符 '2'用,而是字符 2,结果将取决于编码的平台上使用.

没有定义允许s + 2编译1的操作符重载.因此错误.

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


1本质上,原因是因为operator+=不是模板函数,而是std::operator+,并且重载解析将支持非模板函数而不是模板函数.

  • 但我不明白为什么编译器调用`string&operator + =(char c);`但不是`字符串运算符+(const string&lhs,char rhs);`? (2认同)
  • s + = 2编译的事实确实感觉像是一个缺陷 (2认同)
  • 另请参阅此问题,该问题涉及[为什么不是自动向下转换应用于模板函数?](/sf/ask/3185446071/功能). (2认同)

Cor*_*mer 12

添加到您的正确方法string

std::string s;
s += std::to_string(2);
s = s + std::to_string(2);
Run Code Online (Sandbox Code Playgroud)

  • @AndreKampling 2017年.除非特别标记问题或以其他方式提及C++ 03,否则可以假设C++ 11支持可用. (4认同)
  • @CSM"一般推荐"?那为什么会这样?函数`std :: to_string`在这个上下文中是完全合理的,并且是为此目的而创建的. (4认同)
  • 请注意,[std :: to_string](http://de.cppreference.com/w/cpp/string/basic_string/to_string)仅适用于C++ 11及更高版本. (3认同)