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

Я использую 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;
};

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

13

Решение

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

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

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

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

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

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

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

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

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

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

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

21

Другие решения

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

3

По вопросам рекламы ammmcru@yandex.ru