将int追加到std :: string

时间:2017-08-04 11:19:12

标签: c++ stdstring

我尝试了两种不同的方式将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?

在该问题中,没有答案使用+=运算符。+=之间的差异 而+的{​​{1}}运算符是解决我疑问的关键。

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

4 个答案:

答案 0 :(得分:46)

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

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

由于适合较低类型的值可以自动转换为该类型,因此在表达式s += 2中,2 视为int,但是{{1相反。它与<{1}}具有完全相同的效果。附加了带有ASCII码2(STX)的字符,字符&#39; 2&#39; (ASCII值为50或0x32)。

但是,string没有像char这样的重载成员函数,s += '\x02'不是有效表达式,因此在编译期间会抛出错误。 (更多内容)

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

string operator+(int)

对于关注为什么2不会被s + 2自动转换为s = s + char(2); // or (char)2 s = s + std::string(2); s = s + std::to_string(2); // C++11 and above only 的人,

char

以上是operator+中plus运算符的原型 [note] ,因为它是模板函数,需要同时实现{{1}和template <typename CharT> basic_string<CharT> operator+(const basic_string<CharT>& lhs, CharT rhs); ,这是冲突的。有关详细信息,请参阅Why isn't automatic downcasting applied to template functions?

同时,s + 2的原型是:

operator+<char>

你看,这里没有模板(它是一个类成员函数),所以编译器从类实现中推断出CharT是operator+<int>类型,operator+=自动转换为{{1} }}。

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

答案 1 :(得分:42)

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

没有定义运算符重载以允许std::to_string(2)编译 1 。因此错误。

两种情况下的解决方案都是使用int而不是operator+=文字2。

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

答案 2 :(得分:12)

添加到string的正确方法是

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

答案 3 :(得分:2)

虽然@CoryKramer的答案为您提供了向字符串添加整数的正确方法,但它并不能解释为什么指令s = s + 2无法编译。

两条指令之间的区别在于,在第一条指令中,您使用std::string的{​​{3}},而在第二条指令中,编译器会尝试将2转换为字符串。

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