Я использую 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;
};
Я хотел бы, чтобы этот класс генерировал конструктор / назначение перемещения. Является ли тот факт, что у меня нет тривиального конструктора, причиной того, что я не получил ход? Или есть другие факторы, которые влияют на это?
Эта часть C ++ 11, к сожалению, постоянно меняется. И что бы ни говорил стандарт, VC11 пока не сможет его реализовать. Так что на сегодня я не верю, что вы сможете рассчитывать на сгенерированных участников движения.
Тем не менее, это хороший вопрос, и я хотел получить хороший ответ на него.
В общем, компилятор должен генерировать элементы перемещения, если у вас нет ни объявленных пользователем элементов копирования, ни деструктора. = default
а также = delete
считается как объявленный пользователем. Если вы объявите один элемент перемещения (например, конструктор перемещения), другой не будет сгенерирован неявно.
К сожалению, C ++ 11 продолжает говорить, что иногда члены перемещения неявно удаляются при объявлении с =default
и иногда их генерация зависит от того, имеют ли базы и члены элементы перемещения или тривиально копируемые. Это слишком сложно и иногда дает удивительное поведение. Вот проблема CWG, отслеживающая эту ошибку:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1402
Когда я пишу это, проблема не имеет правильного решения. Я ожидаю, что это изменится примерно через неделю. На совещании по стандартам осени C ++ 2012 года в Портленде, штат Орегон, было достигнуто соглашение, которое в основном гласит:
= default
,Короче говоря, я ожидаю, что исправленная формулировка CWG 1402 просто скажет:
В общем, компилятор должен генерировать элементы перемещения, если у вас нет
объявленные пользователем копии участников, ни деструктор.= default
а также= delete
считается как объявленный пользователем. Если вы объявляете одного участника перемещения (например, перемещение
конструктор), другой не будет сгенерирован неявно.
И если вы=default
член движения, вы получите то, что движется
каждая база и член.
(в надлежащей стандартизации). Я еще не видел формулировку, которая скажет это. Джейсон Меррилл пишет это для нас.
Это будет означать, что иногда компилятор неявно генерирует члены броска хода. Но мы шли за простыми правилами, которые, тем не менее, делали правильные вещи большую часть времени (мало сюрпризов).
Чтобы более прямо ответить на это, Visual Studio не поддерживает какую-либо версию неявного создания конструктора перемещения / назначения. Таким образом, вы должны вручную выписать их, всегда.