В конструкторе копирования есть две сомнительные вещи.
Во-первых, вы сделали конструктор копирования явным (что вызывает сомнения), поэтому вам (теоретически) нужно сделать:
Foo d( (Foo()) );
Во-вторых, ваш конструктор копирования берет ссылку, а не ссылку const
, что означает, что вы не можете использовать ее с временной Foo
.
Лично я бы просто удалил explicit
из конструктора копирования и заставил его взять ссылку const
, если это возможно.
Обратите внимание, что explicit
в вашем конструкторе по умолчанию не влияет. [*] explicit
влияет только на конструкторы, которые могут быть вызваны одним параметром. Это предотвращает их использование для неявных преобразований. Для конструкторов, которые принимают только ноль или только два или более параметров, это не имеет никакого эффекта.
[Примечание: может быть разница между:
Foo d;
и
Foo d = Foo();
но в этом случае у вас есть объявленный пользователем конструктор по умолчанию, так что это не применяется.]
Edit:
[*] Я только что дважды проверил это, и 12.3.1 [class.conv.ctor] говорит, что вы можете сделать конструктор по умолчанию explicit
. В этом случае конструктор будет использоваться для выполнения default-initialization или value-initialization . Честно говоря, я не понимаю значения этого, как будто у вас есть конструктор, объявленный пользователем, тогда это не POD-тип, и даже локальные объекты не-POD-типа инициализируются по умолчанию, если у них нет инициализатора который говорит этот пункт, может быть сделан конструктором explicit
по умолчанию. Возможно, кто-то может указать на угловой случай, когда это действительно имеет значение, но сейчас я не вижу, какое влияние explicit
оказывает на конструктор по умолчанию.