Есть два существующих вопроса об замене векторных элементов, которые не могут быть назначены:
Типичная причина того, что объект не может быть присвоен, состоит в том, что его определение класса включает в себя const
членов и, следовательно, имеет свой operator=
.
std::vector
требует, чтобы его тип элемента был назначен. И действительно, по крайней мере, используя GCC, ни прямое присвоение (vec[i] = x;
), ни комбинация erase()
и insert()
, чтобы заменить элемент, работают, когда объект не может быть назначен.
Может ли функция, подобная следующей, которая использует vector::data()
, прямое уничтожение элементов и размещение нового с помощью конструктора копирования, используется для замены элемента без возникновения поведения undefined?
template <typename T>
inline void replace(std::vector<T> &vec, const size_t pos, const T& src)
{
T *p = vec.data() + pos;
p->~T();
new (p) T(src);
}
Ниже приведен пример используемой функции. Это компилируется в GCC 4.7 и, похоже, работает.
struct A
{
const int _i;
A(const int &i):_i(i) {}
};
int main() {
std::vector<A> vec;
A c1(1);
A c2(2);
vec.push_back(c1);
std::cout << vec[0]._i << std::endl;
/* To replace the element in the vector
we cannot use this: */
//vec[0] = c2;
/* Nor this: */
//vec.erase(begin(vec));
//vec.insert(begin(vec),c2);
/* But this we can: */
replace(vec,0,c2);
std::cout << vec[0]._i << std::endl;
return 0;
}