[英]Concatenation of std::string and int leads to a shift. Why?
Today I was surprised when trying to concatenate an std::string
with an int
.今天,当我尝试将
std::string
与int
连接时,我感到很惊讶。 Consider the following MWE:考虑以下 MWE:
#include <iostream>
#include <string>
void print(const std::string& text)
{
std::cout << "The string is: " << text << ".\n";
}
int main()
{
print("iteration_" + 1);
return 0;
}
Instead of printing而不是打印
The string is: iteration_1.
which I would expect, it prints我希望,它打印
The string is: teration_.
What exactly is going on in the background?后台到底发生了什么? Does the string for some reason get converted into
char[]
or something of the sort?字符串是否由于某种原因被转换为
char[]
或类似的东西? The documentation of operator+ does not list any with an std::string
and int
. operator+ 的文档没有列出任何带有
std::string
和int
的内容。
And what is the proper way of concatenating an std::string
with a number?将
std::string
与数字连接的正确方法是什么? Do I really have to throw them both into an std::stringstream
or convert the number into std::string
explicitely with std::to_string()
?我真的必须将它们都放入
std::stringstream
或使用std::to_string()
将数字显式转换为std::string
吗?
This line is the problem:这条线是问题所在:
print("iteration_" + 1);
The string literal is decaying to a char*
.字符串文字正在衰减为
char*
。 You are adding 1
to this char*
, moving it to the next character.您正在向此
char*
添加1
,将其移动到下一个字符。
If you wanted to add the string "1"
to the end of your literal, a fairly simple way is to pass the string literal to the std::string
constructor and convert the 1
to a string manually.如果您想将字符串
"1"
添加到文字的末尾,一种相当简单的方法是将字符串文字传递给std::string
构造函数并手动将1
转换为字符串。 For example:例如:
print(std::string("iteration_") + std::to_string(1));
Does the string for some reason get converted into char[]
字符串是否由于某种原因被转换为 char[]
Actually it is the other way around.事实上,情况恰恰相反。
"iteration_"
is a char[11]
which decays to a const char*
when you add 1
. "iteration_"
是一个char[11]
,当您添加1
时它会衰减为const char*
。 Incrementing the pointer by one makes it point to the next character in the string.将指针加一使其指向字符串中的下一个字符。 This is then used to construct a temporary
std::string
that contains all but the first character.然后使用它来构造一个临时的
std::string
,它包含除第一个字符之外的所有字符。
The documentation you link is for operator+
of std::string
, but to use that you need a std::string
first.您链接的文档适用于
std::string
的operator+
,但要使用它,您首先需要std::string
。
"iteration_"
is not std::string
, but const char[]
. "iteration_"
不是std::string
,而是const char[]
。 Which decays to const char*
, and "iteration_" + 1
just performs pointer arithmetic and move the pointer pointing to the next char
(ie 't'
), then you got the c-style string "teration_"
.衰减到
const char*
,而"iteration_" + 1
只是执行指针算术并将指针移动到下一个char
(即't'
),然后你就得到了 c 风格的字符串"teration_"
。
You can usestd::to_string
to convert int
to std::string
, then concatenate them.您可以使用
std::to_string
将int
转换为std::string
,然后将它们连接起来。 eg例如
print("iteration_" + std::to_string(1));
For this case std::operator+(std::basic_string) is called and the 1st argument "iteration_"
is converted to std::string
implicitly and then passed to operator+
, then the concatenated std::string
is passed to print
.对于这种情况,调用std::operator+(std::basic_string)并将第一个参数
"iteration_"
隐式转换为std::string
然后传递给operator+
,然后将连接的std::string
传递给print
。
If you try to use the following:如果您尝试使用以下内容:
std::string str = "iteration" + 1;
compiler will throw the warning:编译器会抛出警告:
warning: adding 'int' to a string does not append to the string [-Wstring-plus-int]
警告:将“int”添加到字符串不会 append 到字符串 [-Wstring-plus-int]
It is because you are incrementing the pointer to "iteration" string by 1 which means that now "teration" string is being assigned to str
variable.这是因为您将指向“迭代”字符串的指针增加 1,这意味着现在“迭代”字符串被分配给
str
变量。
The proper way of concatenating would be:连接的正确方法是:
std::string str = "iteration" + std::to_string(1);
The expression "iteration_" + 1
is a const char[11]
literal added to the int
1.表达式
"iteration_" + 1
是添加到int
1 的const char[11]
文字。
In that expression, "iteration_"
decays to a const char*
pointer to the first element of the array.在该表达式中,
"iteration_"
衰减为指向数组第一个元素的const char*
指针。 + 1
then takes place in pointer arithmetic on that pointer. + 1
然后发生在该指针的指针算术中。 The entire expression evaluates to a const char*
type (pointing to the first t
) which is a valid NUL-terminated input to a std::string
constructor!整个表达式的计算结果为
const char*
类型(指向第一个t
),它是std::string
构造函数的有效 NUL 终止输入! (The anonymous temporary std::string
binds to the const std::string&
function parameter.) (匿名临时
std::string
绑定到const std::string&
function 参数。)
This is completely valid C++ and can occasionally be put to good use.这是完全有效的 C++,偶尔可以很好地使用。
If you want to treat +
as a concatenation, then如果您想将
+
视为串联,则
print("iteration_" + std::to_string(1));
is one way.是一种方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.