Объявление неявно объявленного конструктора копирования фактически не подавляется. Это просто не вызывается из-за правил разрешения перегрузки.
Неявно объявленный конструктор копирования имеет форму Foo(const Foo&)
. Важной частью этого является то, что требуется постоянная ссылка. Ваш шаблон конструктора использует неконстантную ссылку.
a
не является константой, поэтому неконстантный пользовательский шаблон конструктора предпочтительнее неявно объявленного конструктора копирования. Чтобы вызвать неявно объявленный конструктор копирования, вы можете сделать a
const:
const Foo a;
Foo b(a);
или вы можете использовать static_cast
для получения константной ссылки на a
:
Foo a;
Foo b(static_cast<const Foo&>(a));
Правила разрешения перегрузки, описывающие это, находятся в основном в §13.3.3.2 / 3 FCD C ++ 0x. Этот конкретный сценарий с комбинацией ссылок lvalue и rvalue описан в различных примерах на стр. 303.
Шаблон конструктора переменной будет подавлять неявно объявленный конструктор по умолчанию, поскольку шаблон конструктора переменной объявлен пользователем, а неявно объявленный конструктор по умолчанию предоставляется только при отсутствии объявленных пользователем конструкторов (C ++ 0x FCD §12.1 / 5 ):
Если для класса X
не объявлен пользовательский конструктор, конструктор, не имеющий параметров, неявно объявляется как дефолтный.
Шаблон конструктора с переменными параметрами не будет подавлять неявно объявленный конструктор копирования, поскольку только конструктор без шаблона может быть конструктором копирования (C ++ 0x FCD §12.8 / 2, 3 и 8):
Не шаблонный конструктор для класса X
является конструктором копирования, если его первый параметр имеет тип X&
, const X&
, volatile X&
или const volatile X&
, и либо отсутствуют другие параметры, либо все другие параметры имеют аргументы по умолчанию.
Не шаблонный конструктор для класса X
является конструктором перемещения, если его первый параметр имеет тип X&&
, const X&&
, volatile X&&
или const volatile X&&
, а других параметров либо нет, либо все остальные параметры имеют аргументы по умолчанию.
Если определение класса не объявляет явно конструктор копирования, и не существует объявленного пользователем конструктора перемещения, конструктор копирования неявно объявляется как дефолтный.