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