将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。
int和std::string之间没有隐式转换。 然而,你可以把一个int为char ,所以这就是s += 2原因。