简体   繁体   English

std::string 和 int 的串联会导致转变。 为什么?

[英]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::stringint连接时,我感到很惊讶。 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::stringint的内容。

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::stringoperator+ ,但要使用它,您首先需要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_stringint转换为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

LIVE居住

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM