将int附加到std :: string

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

 #include <string> int main() { std::string s; s += 2; // compiles correctly s = s + 2; // compiler error return 0; } 

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

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

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

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

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

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

由于适合较低types的值可以自动转换为该types,因此在expression式s += 2 ,2 被视为int ,而是被视为char 。 它和s += '\x02'效果完全一样。 附加ASCII代码2(STX)的字符不是字符'2'(ASCII值为50或0x32)。

但是,string没有像string operator+(int)那样的重载成员函数,因此s + 2不是有效的expression式,因此在编译期间会引发错误。 (更多下面)

你可以用下面的方法在string中使用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不会自动转换成operator+ char

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

以上是s + 2的加号运算符的原型[note] ,因为它是一个模板函数,所以需要实现operator+<char>operator+<int> ,这是冲突的。 有关详细信息,请参阅为什么不将自动向下转换应用于模板函数?

同时, operator+=的原型是:

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

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


注意:从C ++标准包含源复制时,不必要的代码被剥离。 这包括模板类“basic_string”的typename 2和3(Traits and Allocator),以及不必要的下划线,以提高可读性。

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

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

在这两种情况下的解决scheme是使用std::to_string(2)而不是int文字2。


1实质上,原因是因为operator+=不是模板函数,而是std::operator+是,而重载parsing将有利于模板之外的非模板函数。

添加到你的string的正确方法是

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

虽然@CoryKramer答案给你一个正确的方法来添加一个整数string,它不能解释为什么指令s = s + 2不编译。

两条指令的区别在于,第一条指令使用了std::string的+ =运算符,而在第二条指令中,编译器试图将2转换为string。

intstd::string之间没有隐式转换。 然而,你可以把一个intchar ,所以这就是s += 2原因。