Today I was surprised when trying to concatenate an std::string
with an int
. Consider the following 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? The documentation of operator+ does not list any with an std::string
and int
.
And what is the proper way of concatenating an std::string
with a number? Do I really have to throw them both into an std::stringstream
or convert the number into std::string
explicitely with std::to_string()
?
This line is the problem:
print("iteration_" + 1);
The string literal is decaying to a char*
. You are adding 1
to this char*
, moving it to the next character.
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. For example:
print(std::string("iteration_") + std::to_string(1));
Does the string for some reason get converted into char[]
Actually it is the other way around. "iteration_"
is a char[11]
which decays to a const char*
when you add 1
. 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.
The documentation you link is for operator+
of std::string
, but to use that you need a std::string
first.
"iteration_"
is not std::string
, but 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_"
.
You can usestd::to_string
to convert int
to std::string
, then concatenate them. 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
.
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]
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.
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.
In that expression, "iteration_"
decays to a const char*
pointer to the first element of the array. + 1
then takes place in pointer arithmetic on that pointer. 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! (The anonymous temporary std::string
binds to the const std::string&
function parameter.)
This is completely valid C++ and can occasionally be put to good use.
If you want to treat +
as a concatenation, then
print("iteration_" + std::to_string(1));
is one way.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.