coming from Java, I tried to use string concatenation on a string and an int using "x" + i. I quickly found out that in C++ one needs proper conversion, for example in C++11 one can achieve this by std::to_string().
What I do not understand is what happens if one forgets about the conversion. Let me give you an example.
This code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
#include <vector>
usingnamespace std;
int main(int argc, char *argv[]) {
vector<int> v(1);
for ( int i = 0; i < 10; i++ ) {
v.push_back(i);
}
for ( int i = 0; i < 10; i++ ) {
string s = "x" + i;
cout << s << "\n";
}
return 0;
}
results in this output:
1 2 3 4 5 6 7 8 9 10 11
x
vector::_M_emplace_back_aux
ector::_M_emplace_back_aux
ctor::_M_emplace_back_aux
tor::_M_emplace_back_aux
or::_M_emplace_back_aux
r::_M_emplace_back_aux
Any help explaining this would be very much appreciated.
It looks like you're incrementing the pointer, and what you're seeing is undefined behavior because you're accessing the array out of bounds.
Perhaps this will help illustrate:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
#include <vector>
usingnamespace std;
int main(int argc, char *argv[]) {
vector<int> v(1);
for ( int i = 0; i < 10; i++ ) {
v.push_back(i);
}
for ( int i = 0; i < 10; i++ ) {
string s = "abcdefghijklmnopqrstuvwxyz" + i;
cout << s << "\n";
}
return 0;
}
That looks like straight up Undefined Behaviour (UB) to me. Anything could happen, on cpp.sh on my machine, I had this output:
;L ;L ;L ;L L
I guess the real question is how to make the compiler complain in this situation?
It's a wonder the compiler doesn't seem to complain about a type mismatch. I wonder if it is somehow using one of the rvalue overloads for std::string operator+ ? Perhaps one of the experts here can answer that.
Good Luck !!
Edit: I didn't see jlb post while I was writing mine :+)
See the reference for string. Here is the page for the '+' operator: http://www.cplusplus.com/reference/string/string/operator+/
It covers the available possibilities, which always include a std::string as at least one of the operands. The other choices are: a single character or a c-string (a null-terminated array of such characters).
When you use the '+' operator, the compiler attempts to find a matching function for the given arguments among those available.
So if I understand correctly, calling the operator + with a string and an int as arguments is simply undefined?
No, it is not undefined. It increments the pointer. As long as it is within the bounds of the string the result is actually defined. A problem (as always) is when it gets out of bounds (in this case i > 1 which will beyond the terminating 0)
I see, so when calling the string operator the int value is taken as string& in
First, this is not the "string operator". It is an overload of the binary operator+ that takes a combination of std::string and other types (such as pointer-to-char or another std::string object) and returns a std::string with the concatenated result.
There is no operator+ overload for std::string and int.
In the OP, operator+ worked on a pointer type and an int. There was no std::string involved until the result of that was calculated.
To be clear: "x" is a string literal in the c-style string sense. It is just an array of char consisting of the sequence {'x', '\0'}, and in the context it was used it decays into a pointer to the first element. It was this pointer that your int was added to.