2

I understand you can not use operator+ to concatenate an integer to a std::string without converting it to a char* or std::string.

But why does adding an integer returns the tail of a string?

#include <iostream>
#include <string>
int main()
{
    std::string x;
    x = "hello world" + 3;
    std::cout << x << std::endl;
}

Prints: lo world

If you change: x = "hello world" + 8;

We print: rld

What's the reasoning behind this? Undefined behavior?

rocambille
  • 15,398
  • 12
  • 50
  • 68
fqlx
  • 123
  • 1
  • 9

4 Answers4

5

You need to know your types. Firs of all, you are not adding 3 to the std::string. Addition happens before std::string is created. Instead you are adding 3 to the char[12], which is defined, since char array decays to char*, and adding 3 to it advances the pointer by 3 elements. This is exactly what you see.

Than std::string is constructed from the result, and you end up with a tail.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
2

It's equivalent to:

#include <iostream>
#include <string>

int main()
{
    std::string x;
    const char* p = "hello world";
    p = p + 3;
    x = p;
    std::cout << x << std::endl;
}

You can make it safer this way:

#include <iostream>
#include <string>

using namespace std::literals;

int main()
{
    std::string x;
    x = "hello world"s + 3;      // error! won't compile
    std::cout << x << std::endl;
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
0

As you know a string is an array of chars, if you put the + 3 you are stating you are going to take the string from the third position to the end of it

0
int data[5] = { 1, 2, 3, 4, 5 };
int *dp = data;
std::cout << *(dp + 3) << '\n';

Now, here, dp + 3 points at the 4 in the data array; that's just pointer arithmetic. So *(dp + 3) is 4, and that's what you see in the output stream.

Same thing with a char*: adding an integer to it gives you a new pointer value, offset from the original by the value of the integer:

char data[5] = "abcd";
char *dp = data;
std::cout << *(dp + 3) << '\n';

dp points at the beginning of the array, and dp + 3 points at the letter 'd'. So *(dp + 3) is d, and that's what you see in the output.

You get the same thing when you use a pointer and an offset to initialize an object of type std::string: the pointer plus offset points at a location inside the char array, and the resulting std::string object holds a copy of the characters from that location out to the terminating null character.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165