Сегодня я столкнулся с довольно тонкой проблемой, по которой хотел бы узнать ваше мнение.
Рассмотрим следующий класс идиомы разделяемого тела:
struct S
{
S() : p_impl(new impl) {}
private:
struct impl;
boost::shared_ptr<impl> p_impl;
};
Веселье появляется, когда вы пытаетесь поместить их в векторы следующим образом:
std::vector<S> v(42);
Теперь, по крайней мере, с MSVC 8, все элементы в v
имеют один и тот же член impl
. Фактически, причиной этого является конструктор vector
:
template <typename T, typename A = ...>
class vector
{
vector(size_t n, const T& x = T(), const A& a = A());
...
};
Под сценой создается только один объект S
по умолчанию, элементы n
из ] vector
скопирован из него.
Теперь, в C ++ 11, есть ссылки на rvalue. Так что это не может так работать. Если вектор
сконструирован как
std::vector<S> v(42);
, то, скорее всего, реализации по умолчанию выберут создание объектов n
внутри вектора, поскольку копирование может быть недоступно. В данном случае это было бы критическим изменением.
Мой вопрос:
std :: vector
должен иметь конструктор, определенный как указано выше, т.е. с аргументом по умолчанию? В частности, есть ли гарантия, что записи векторного объекта будут скопированы, а не созданы по умолчанию? PS: Пожалуйста, не комментируйте конструктор по умолчанию для класса S
выше. Это было или реализация некоторой формы ленивого построения.