将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
原因。