[英]Concatenation of std::string and int leads to a shift. Why?
今天,当我尝试将std::string
与int
连接时,我感到很惊讶。 考虑以下 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;
}
而不是打印
The string is: iteration_1.
我希望,它打印
The string is: teration_.
后台到底发生了什么? 字符串是否由于某种原因被转换为char[]
或类似的东西? operator+ 的文档没有列出任何带有std::string
和int
的内容。
将std::string
与数字连接的正确方法是什么? 我真的必须将它们都放入std::stringstream
或使用std::to_string()
将数字显式转换为std::string
吗?
这条线是问题所在:
print("iteration_" + 1);
字符串文字正在衰减为char*
。 您正在向此char*
添加1
,将其移动到下一个字符。
如果您想将字符串"1"
添加到文字的末尾,一种相当简单的方法是将字符串文字传递给std::string
构造函数并手动将1
转换为字符串。 例如:
print(std::string("iteration_") + std::to_string(1));
字符串是否由于某种原因被转换为 char[]
事实上,情况恰恰相反。 "iteration_"
是一个char[11]
,当您添加1
时它会衰减为const char*
。 将指针加一使其指向字符串中的下一个字符。 然后使用它来构造一个临时的std::string
,它包含除第一个字符之外的所有字符。
您链接的文档适用于std::string
的operator+
,但要使用它,您首先需要std::string
。
"iteration_"
不是std::string
,而是const char[]
。 衰减到const char*
,而"iteration_" + 1
只是执行指针算术并将指针移动到下一个char
(即't'
),然后你就得到了 c 风格的字符串"teration_"
。
您可以使用std::to_string
将int
转换为std::string
,然后将它们连接起来。 例如
print("iteration_" + std::to_string(1));
对于这种情况,调用std::operator+(std::basic_string)并将第一个参数"iteration_"
隐式转换为std::string
然后传递给operator+
,然后将连接的std::string
传递给print
。
如果您尝试使用以下内容:
std::string str = "iteration" + 1;
编译器会抛出警告:
警告:将“int”添加到字符串不会 append 到字符串 [-Wstring-plus-int]
这是因为您将指向“迭代”字符串的指针增加 1,这意味着现在“迭代”字符串被分配给str
变量。
连接的正确方法是:
std::string str = "iteration" + std::to_string(1);
表达式"iteration_" + 1
是添加到int
1 的const char[11]
文字。
在该表达式中, "iteration_"
衰减为指向数组第一个元素的const char*
指针。 + 1
然后发生在该指针的指针算术中。 整个表达式的计算结果为const char*
类型(指向第一个t
),它是std::string
构造函数的有效 NUL 终止输入! (匿名临时std::string
绑定到const std::string&
function 参数。)
这是完全有效的 C++,偶尔可以很好地使用。
如果您想将+
视为串联,则
print("iteration_" + std::to_string(1));
是一种方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.