Подтвердить что ты не робот

Когда компилятор должен генерировать конструктор перемещения?

Я использую VS11 и использую следующее:

class ContextWrapper
{
public:

    ContextWrapper()
    {
    } //it should be defaulted I *guess* in order to have automatic move constructor ?
      // no support in VS11 for that now  

    Context* GetContext()
    {
        return this->context.get();
    }

    void SetContext(std::unique_ptr<Context> context)
    {
        this->context = std::move(context);
    }

    //ContextWrapper(ContextWrapper&& other):  context(std::move(other.context))
    //{
    //} // I would like this to be generated by the compiler

private:
    ContextWrapper(const ContextWrapper&);
    ContextWrapper& operator= (const ContextWrapper&);

    std::unique_ptr<Context> context;
};

Я хотел бы, чтобы этот класс создавал конструктор/назначение перемещения. Является ли тот факт, что у меня нет тривиального конструктора, почему я не могу двигаться? Или есть другие факторы, которые влияют на это?

4b9b3361

Ответ 1

Эта часть С++ 11, к сожалению, находится в движении. И что бы ни сказал стандарт, VC11 еще не смог реализовать его. Поэтому на сегодняшний день я не верю, что вы сможете рассчитывать на сгенерированные элементы перемещения.

Однако, это хороший вопрос, и я хотел получить хороший ответ на него.

В общем, компилятор должен генерировать элементы перемещения, если у вас нет объявленных пользователем элементов копирования или деструктора. = default и = delete считается объявленным пользователем. Если вы объявите один элемент перемещения (например, конструктор перемещения), другой не будет неявно сгенерирован.

К сожалению, в С++ 11 говорится, что иногда элементы перемещения неявно удаляются при объявлении с помощью =default, и иногда их генерация зависит от того, имеют ли базы и члены элементы перемещения или тривиально скопируются. Все это слишком сложно и иногда дает удивительное поведение. Вот проблема CWG, отслеживающая эту ошибку:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1402

Как я пишу это, проблема не имеет правильной предлагаемой резолюции. Я ожидаю, что это изменится примерно через неделю. На совещании Fall С++ 2012 в Портленде, OR, было достигнуто соглашение, в котором в основном говорится:

  • Компилятор никогда не будет неявно удалять элементы перемещения.
  • Неявное поколение элементов перемещения всегда будет таким же, как = default.
  • Неявная генерация не будет зависеть от тривиальности баз или членов, а также от того, могут ли они бросить при перемещении.

В двух словах я ожидаю, что исправленная формулировка CWG 1402 просто скажет:

В общем, компилятор должен генерировать элементы перемещения, если у вас нет объявленные пользователем члены копии и деструктор. = default и = deleteсчитается объявленным пользователем. Если вы объявите один элемент перемещения (например, переместите конструктор), другой не будет неявно сгенерирован. И если вы =default перемещаете элемент, вы получите что-то, что движется каждой базой и членом.

(при правильной стандартизации). Я еще не видел формулировки, которые скажут это. Джейсон Меррилл пишет это нам.

Это будет означать, что иногда компилятор будет неявно генерировать метательные элементы перемещения. Но мы шли по простым правилам, которые все-таки делали большую часть времени (мало сюрпризов).

Ответ 2

Чтобы более точно ответить на это, Visual Studio не поддерживает какую-либо версию создания неявного перемещения конструктора/назначения. Поэтому вы должны вручную записывать их всегда.