Устраняет ли явное перемещение ctor неявное копирование ctor?

Я прочитал в принятом ответе Вот тот:

[a] конструктор копирования и оператор копирования не будут сгенерированы для класса, который явно объявляет конструктор перемещения или же оператор присваивания перемещения

Я заметил (g ++ 4.7.2), что если вы определите конструктор перемещения, он будет использоваться, например, с push_back()тогда как, если все, что вы делаете, это = delete конструктор копирования, вы не получаете неявный конструктор перемещения — вы получаете ошибку. [… что заставляет меня задуматься, какой из них (переместить или скопировать) на самом деле используется, если вы ничего не делаете явно …]

Тем не мение, эта онлайн ссылка не дает таких же явных обещаний относительно конструктора копирования не будучи неявно определенным, когда вы определяете конструктор перемещения.

Итак, мой вопрос, является ли первая цитата гарантируется стандартом (включая «или же»)? Я бы предпочел, чтобы с некоторыми классами, которым нужен явный деструктор, чтобы завершить «правило пяти» всего лишь конструктором перемещения и (удаленным) оператором перемещения и полагаться на неявные методы копирования не определяется Если я не могу положиться на это, то мне придется явно =delete их — но это много потенциально лишних вещей.

4

Решение

Итак, мой вопрос, является ли первая цитата гарантируется стандартом (включая «или же»)?

Да, ваша первая цитата гарантируется стандартом.

Цитата из стандарта (черновик n3690):

12.8 Копирование и перемещение объектов класса [class.copy]

7 / Если определение класса явно не объявляет конструктор копирования, он объявляется неявно. Если определение класса объявляет конструктор перемещения или оператор присваивания перемещения, неявно объявленный конструктор копирования определяется как удаленный; в противном случае он определяется как дефолтный (8.4). Последний случай считается устаревшим, если в классе есть объявленный пользователем оператор копирования или объявленный пользователем деструктор.

6

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

Интересное продолжение почему?

В C ++ 98 был Правило трех:

Если вы определили одно из следующего, вы должны определить все три:

  • деструктор
  • конструктор копирования
  • оператор копирования

Это эмпирическое правило было создано, потому что многие люди думали только об освобождении ресурса, содержащегося в деструкторе, и забывали о последствиях, которые это специальное поведение имело для копий.

Когда наступил C ++ 11, некоторые люди утверждали, что эта проблема была вызвана определением языка по умолчанию и что было бы лучше, если оглянуться назад, не предоставлять их по умолчанию. Конечно, C предоставляет их по умолчанию (для struct) так…

… некоторые предположили, что на самом деле правило трех может быть применено компилятором; или, по крайней мере, поскольку изменение существующего поведения может привести к поломке существующего кода, компилятор может принудительно использовать подвесную связь с правилом трех, когда речь идет о конструкторе перемещения или операторе присваивания перемещения (что гарантирует новый код C ++ 11).

Правило пяти:

Если вы определите один из следующих пунктов, вы должны определить все пять:

  • деструктор
  • переместить конструктор
  • оператор присваивания перемещения
  • конструктор копирования
  • оператор копирования

таким образом был почти полностью реализован как:

  • если вы определяете конструктор перемещения или оператор присваивания перемещения, остальные 4 метода неявно удаляются (если вы их не предоставите)
  • если вы определяете деструктор, конструктор копирования или оператор присваивания, конструктор перемещения и оператор присваивания перемещения неявно удаляются (если вы их не предоставите)

второе утверждение немного неполно по причинам обратной совместимости с существующим кодом C ++ 98 (который должен компилироваться как C ++ 11 без изменения поведения).

2

По вопросам рекламы [email protected]