Тонкий момент заключается в том, что operator+
занимает Distance
; т.е. целое число со знаком. Если вы увеличиваете итератор без знака, вы можете потерять точность и столкнуться с неожиданностью. Например, в 64-битной системе
std::size_t n = (1 << 64) - 2;
std::vector<double> vec(1 << 64);
std::vector<double> slice(vec.begin() + n, vec.end());
приводит к неопределенному поведению. С g++
или clang
вы можете попросить компилятор предупредить вас о таких нежелательных преобразованиях с флагом предупреждения -Wsign-conversion
, который не является частью канонического -Wall
или -Wextra
.
Обходной путь - работать с указателем напрямую
std::vector<double> slice(vec.data() + n, vec.data() + vec.size());
Это не красиво, но правильно. В некоторых случаях вам нужно создать итератор вручную, например
std::vector<double>::iterator fromHere{vec.data() + n};
vec.erase(fromHere, vec.end());