Копировать-построить из ссылки - PullRequest
2 голосов
/ 16 ноября 2011

Рассмотрим этот код

class Foo {
private:
    Bar bar; //note: no reference

public:
   Foo(Bar& b) : bar(b) { }
};

Будет ли Bar сконструирован с копированием?

Ответы [ 2 ]

3 голосов
/ 16 ноября 2011

Это зависит от сигнатур открытых конструкторов Bar, явно или неявно определенных.

Начнем с того, что стандарт C ++ допускает неявное преобразование ссылок при условии единственного различия вОсновным типом является то, что тип назначения имеет, по крайней мере, квалифицированное по cv , чем тип источника, используя частичное упорядочение, определенное в этой таблице (C ++ 11, §3.9.3 / 4):

без квалификатора cv <<code>const
без квалификатора cv <<code>volatile
без квалификатора cv <<code>const volatile
const <<code>const volatile
volatile <<code>const volatile

Итак, учитывая это, а также §12.8 / 2:

Не шаблонный конструктор для класса X является конструктором копирования, если его первый параметр имеет тип X&, const X&, volatile X& или const volatile X&, и другие параметры отсутствуют.или же все остальные параметры имеют аргументы по умолчанию.

, если Bar имеет конструктор с любым следующегоg подписей:

Bar(Bar&);
Bar(Bar const&);
Bar(Bar volatile&);
Bar(Bar const volatile&);

, тогда да, b будет скопировано в Foo::bar.


РЕДАКТИРОВАТЬ: Это былонеправильно, я думал о operator= и подробностях квалификации в качестве оператора назначения перемещения.

Обратите внимание, что возможно иметь подходящий конструктор, который не является конструктором копирования:

Bar(Bar);

Это будет работать (читай: компилировать), но технически это не конструктор копирования.

1 голос
/ 16 ноября 2011

Да, ваша переменная-член bar будет сгенерирована копированием, это одно из преимуществ использования списка инициализаторов по сравнению с присвоением значения в теле конструктора.

Если класс Barне имеет доступного конструктора копирования, и компилятор не может сгенерировать конструктор по умолчанию, код не сможет скомпилироваться.

Когда вы передаете ссылку на конструктор копирования, вы обычно должны сделать его constссылка.

...