std :: vector, конструкция по умолчанию, C ++ 11 и критические изменения

Сегодня я столкнулся с довольно тонкой проблемой, по которой хотел бы узнать ваше мнение.

Рассмотрим следующий класс идиомы разделяемого тела:

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 внутри вектора, поскольку копирование может быть недоступно. В данном случае это было бы критическим изменением.

Мой вопрос:

  1. Обязан ли стандарт C ++ 03, что std :: vector должен иметь конструктор, определенный как указано выше, т.е. с аргументом по умолчанию? В частности, есть ли гарантия, что записи векторного объекта будут скопированы, а не созданы по умолчанию?
  2. Что стандарт C ++ 11 говорит об этом же пункте?
  3. Я вижу в этом возможность критического изменения между C ++ 03 и C + 11. Эта проблема исследовалась? Решено?

PS: Пожалуйста, не комментируйте конструктор по умолчанию для класса S выше. Это было или реализация некоторой формы ленивого построения.

52
задан Xeo 1 March 2012 в 12:07
поделиться