Рассмотрим следующее, упрощены и неполно, внедрение фиксированного размера вектора:Каким образом std :: putder влияет на контейнеры?
template<typename T>
class Vec {
T *start, *end;
public:
T& operator[](ssize_t idx) { return start[idx]; }
void pop() {
end--;
end->~T();
}
template<typename... U>
void push(U... args) {
new (end) T { std::forward<U>(args)... };
end++;
}
};
Теперь рассмотрим следующую Т:
struct T {
const int i;
};
И следующий случай использования:
Vec<T> v;
v.push(1);
std::cout << v[0].i;
v.pop();
v.push(2);
std::cout << v[0].i;
Оператор индекса использует указатель start
для доступа к объекту. Объект в этой точке был уничтожен pop
, а другой объект был создан в своем хранилище на push(2)
. Если я правильно прочитал документацию, связанную с std::launder, это означает, что поведение v[0]
в строке ниже не определено.
Как следует использовать std :: washmer для исправления этого кода? Нужно ли начинать и заканчивать отмывание каждый раз, когда используется новое место? Текущие реализации stdlib, похоже, используют код, аналогичный тому, который был выше. Не определено ли поведение этих реализаций?
'std :: vector' не был реализован в стандартном C++ с C++ 03. –
@ T.C .: Ухаживать за этим? Учитывая это, знаешь, _is_. –
Возвращаемое значение @LightnessRacesinOrbit 'data()' '(или в C++ 03, '& v [0]') требуется, чтобы разрешить арифметику указателя на нем, а арифметика указателя определена только для указателей в один и тот же массив. 'vector', по очевидным причинам, фактически не может использовать массив внутри. –