将 int 附加到 std::string
Append int to std::string
我尝试了两种不同的方法来将 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?
在那个问题中,没有答案使用 +=
operator.And +=
之间的区别
而 std::string
的 +
运算符是解决我疑惑的关键。
坦率地说,这个问题是解释为什么 c++ 如此难以掌握的一个很好的例子。
添加到 string
的正确方法是
std::string s;
s += std::to_string(2);
s = s + std::to_string(2);
s += 2;
并没有按照您的想法行事。它将重载的 +=
运算符调用到 char
。它不是附加字符'2'
,而是附加值2的字符,结果将取决于您平台上使用的编码。
没有定义运算符重载以允许 s + 2
编译 1。因此错误。
两种情况下的解决方案是使用 std::to_string(2)
而不是 int
文字 2.
1 本质上是因为 operator+=
不是模板函数,而 std::operator+
是,重载解析将有利于非模板函数在模板上。
虽然@CoryKramer 的回答为您提供了将整数添加到字符串的正确方法,但并未解释指令 s = s + 2
无法编译的原因。
这两条指令的区别在于,在第一条指令中,您使用 std::string
的 += operator,而在第二条指令中,编译器尝试将 2
转换为字符串。
int
和 std::string
之间没有隐式转换。但是,您可以将 int
转换为 char
,这就是 s += 2
有效的原因。
TL;DR operator+=
是class string
中的class成员函数,而operator+
是模板函数。
标准classtemplate<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+ 函数:
s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only
对于关心为什么 2 不会自动转换为 char
和 operator+
、
的人
template <typename CharT>
basic_string<CharT>
operator+(const basic_string<CharT>& lhs, CharT rhs);
以上是s + 2
中加号运算符的原型[注意],因为是模板函数,所以需要同时实现operator+<char>
和 operator+<int>
,这是冲突的。有关详细信息,请参阅
同时,operator+=
的原型是:
template <typename CharT>
class basic_string{
basic_string&
operator+=(CharT _c);
};
你看,这里没有模板(它是一个 class 成员函数),因此编译器从 class 实现中推断出 CharT 类型是 char
,并且 int(2)
自动转换为 char(2)
。
注意:从 C++ 标准包含源复制时,不必要的代码被删除。这包括模板 class "basic_string" 的类型名称 2 和 3(特征和分配器)以及不必要的下划线,以提高可读性。
我尝试了两种不同的方法来将 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?
在那个问题中,没有答案使用 +=
operator.And +=
之间的区别
而 std::string
的 +
运算符是解决我疑惑的关键。
坦率地说,这个问题是解释为什么 c++ 如此难以掌握的一个很好的例子。
添加到 string
的正确方法是
std::string s;
s += std::to_string(2);
s = s + std::to_string(2);
s += 2;
并没有按照您的想法行事。它将重载的 +=
运算符调用到 char
。它不是附加字符'2'
,而是附加值2的字符,结果将取决于您平台上使用的编码。
没有定义运算符重载以允许 s + 2
编译 1。因此错误。
两种情况下的解决方案是使用 std::to_string(2)
而不是 int
文字 2.
1 本质上是因为 operator+=
不是模板函数,而 std::operator+
是,重载解析将有利于非模板函数在模板上。
虽然@CoryKramer 的回答为您提供了将整数添加到字符串的正确方法,但并未解释指令 s = s + 2
无法编译的原因。
这两条指令的区别在于,在第一条指令中,您使用 std::string
的 += operator,而在第二条指令中,编译器尝试将 2
转换为字符串。
int
和 std::string
之间没有隐式转换。但是,您可以将 int
转换为 char
,这就是 s += 2
有效的原因。
TL;DR operator+=
是class string
中的class成员函数,而operator+
是模板函数。
标准classtemplate<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+ 函数:
s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only
对于关心为什么 2 不会自动转换为 char
和 operator+
、
template <typename CharT>
basic_string<CharT>
operator+(const basic_string<CharT>& lhs, CharT rhs);
以上是s + 2
中加号运算符的原型[注意],因为是模板函数,所以需要同时实现operator+<char>
和 operator+<int>
,这是冲突的。有关详细信息,请参阅
同时,operator+=
的原型是:
template <typename CharT>
class basic_string{
basic_string&
operator+=(CharT _c);
};
你看,这里没有模板(它是一个 class 成员函数),因此编译器从 class 实现中推断出 CharT 类型是 char
,并且 int(2)
自动转换为 char(2)
。
注意:从 C++ 标准包含源复制时,不必要的代码被删除。这包括模板 class "basic_string" 的类型名称 2 和 3(特征和分配器)以及不必要的下划线,以提高可读性。