Специальные функции-члены в C ++ 0x - PullRequest
3 голосов
/ 19 июля 2010

Статья в Википедии о специальных функциях-членах не содержит ссылок на конструкторы перемещения и операторы присваивания перемещения.

Я хотел бы обновить запись, но я не уверен, что говорит стандарт 0x.

Каковы правила, касающиеся этих двух функций? Они автоматически генерируются компилятором и если да, то когда?


Редактировать: Я обновил страницу Википедии, если кто-то захочет, пожалуйста, помогите сообществу, отредактировав его в форме (при необходимости).

1 Ответ

3 голосов
/ 19 июля 2010

Принимая во внимание, что C ++ 0x еще не совсем стандарт, это может быть изменено. Из FCD (ссылка PDF) конструкторы перемещения и операторы присваивания перемещения действительно могут быть явно дефолтными и даже неявно дефолтными. *****


Я просто процитирую (сильно сокращенно) несколько вещей, которые могут быть полезны для взгляда:

Об явно дефолтных функциях, §8.4.2 / 1-2:

Функция с явным значением по умолчанию должна

  • быть специальной функцией-членом,
  • имеет тот же объявленный тип функции, как если бы он был неявно объявлен,
  • не имеет аргументов по умолчанию и
  • не имеет спецификации-исключения.

Если в первом объявлении явно указано значение по умолчанию,

  • должно быть публично,
  • это не должно быть явным,
  • оно не должно быть виртуальным,
  • неявно считается, что он имеет ту же спецификацию исключений, как если бы она была неявно объявлена ​​(15.4), и
  • в случае конструктора копирования, конструктора перемещения, оператора копирования или оператора назначения перемещения он должен иметь такой же тип параметра, как если бы он был неявно объявлен.

О специальных функциях-членах, §12 / 1:

Конструктор по умолчанию (12.1), конструктор копирования и оператор назначения копирования (12.8), конструктор перемещения и оператор назначения перемещения (12.8) и деструктор (12.4) являются специальными функциями-членами. [Примечание: Реализация будет неявно объявлять эти функции-члены для некоторых типов классов, когда программа явно не объявляет их. Реализация будет неявно определять их, если они используются. См. 12.1, 12.4 и 12,8. —Конечная записка]

О неявно объявленных функциях, §12.8 / 8-11:

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

Неявно объявленный конструктор копирования для класса X будет иметь форму X::X(const X&), если

  • каждый прямой или виртуальный базовый класс B из X имеет конструктор копирования, первый параметр которого имеет тип const B& или const volatile B& и
  • для всех нестатических членов-данных X, которые имеют тип класса M (или его массив), каждый такой тип класса имеет конструктор копирования, первый параметр которого имеет тип const M& или const volatile M&.

В противном случае неявно объявленный конструктор копирования будет иметь вид X::X(X&).

Если определение класса явно не объявляет конструктор перемещения, он будет неявно объявлен как дефолтный, если и только если

  • X не имеет объявленного пользователем конструктора копирования и
  • конструктор перемещения не будет неявно определен как удаленный.

[Примечание: если конструктор перемещения не объявлен неявно или не предоставлен явно, выражения, которые в противном случае вызвали бы конструктор перемещения, могут вместо этого вызвать конструктор копирования. —Конечная записка]

Неявно объявленный конструктор перемещения для класса X будет иметь вид X::X(X&&).

Об неявно удаленных функциях по умолчанию, §12.8 / 12:

Неявно объявленный конструктор копирования / перемещения является встроенным открытым членом своего класса. По умолчанию конструктор копирования / перемещения для класса X определяется как удаленный (8.4.3), если X имеет:

  • вариантный член с нетривиальным соответствующим конструктором и X является объединяющим классом,
  • нестатический член данных типа класса M (или его массив), который не может быть скопирован / перемещен, поскольку разрешение перегрузки (13.3) применительно к соответствующему конструктору M приводит к неоднозначности или функции, которая удаляется или недоступна из дефолтного конструктора или
  • апрямой или виртуальный базовый класс B, который нельзя скопировать / переместить, поскольку разрешение перегрузки (13.3) применительно к соответствующему конструктору B приводит к неоднозначности или функции, которая удаляется или недоступна из конструктора по умолчанию, или
  • для конструктора перемещения - нестатический член данных или прямой или виртуальный базовый класс с типом, который не имеет конструктора перемещения и который не может быть легко скопирован.

§12.8 / 13-18 определяет, как функции должны работать, когда они неявно генерируются.

§12.8 / 19 затем делает то же самое, что и §12.8 / 8, за исключением операторов копирования-назначения и перемещения-назначения.Они достаточно похожи, чтобы не оправдывать цитирование здесь.

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


* Но, как и функции копирования по умолчанию, они могут не всегда иметь правильное поведение!Большая тройка должна стать Большой пятеркой.(Например, Большая тройка реализуется всякий раз, когда нам нужно что-то глубоко копировать. Нам также нужно убедиться, что мы делаем «глубокий ход», когда данные источника обнуляются / сбрасываются. Это , а не сделано неявно.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...