Мое понимание конструктора неявных копий С++ аналогично
T(T const& x) :
base1(x), base2(x) ... ,
var1(x.var1), var2(x.var2)...
{}
Перемещение конструктора, копирование и перемещение также следует по аналогичной схеме.
Почему он не был определен как следующий?
T(T const& x) :
base1(static_cast<base1 const&>(x)),
base2(static_cast<base2 const&>(x)) ... ,
var1(x.var1), var2(x.var2)...
{}
Пример
У меня был класс, который имел неявный оператор конструктора/назначения copy/move, а также некоторые конструкторы преобразования. Я делегировал задание на некоторый класс реализации.
class common_work //common implementation of many work like classes
{
common_work(common_work const&) = default;
common_work(common_work&&) = default;// ... implicit constructors work for me.
//a forwarding constructor which can take many work like objects
template<class T, enable_if<work_like<T> > >
common_work(T&& x) { ... }
};
class work1 //one of the implementation
{
work1(work1 const& ) = default;
work1(work1&& ) = default; ...
common_work impl_;
};
Это было прекрасно, так как конструкторы work1
copy/move вызывали конструктор copy/move для common_work
, а конструктор пересылки использовался другими конструкторами [не показанными в коде], которые преобразуются из другого типа work
.
Тогда я думал унаследовать work1
от common_work
для EBO и других причин. Итак, новый класс work1
выглядел как
class work1 : private common_work
{
work1(work1 const& ) = default;
work1(work1&& ) = default; ...
};
Но поскольку work1
является классом work_like
, конструктор пересылки получает лучшее совпадение, поскольку конструктор copy/move для common_work
требует static_cast
от производной до базы.
ПРИМЕЧАНИЕ.
- Существует аналогичный пример, приведенный Scott Meyers, где построение копирования вызывает конструктор пересылки в качестве конструктора копирования, требует добавления константы, а пересылка конструктор не требует. Но я думаю, что эта проблема возникает из-за неправильного дизайна класса, тогда как проблема здесь связана с аргументом, переданным базовому классу при неявной копировании/перемещении, не является точным совпадением.
- Я не могу написать универсальный конструктор переадресации/назначение и удалить неявные, потому что удаленные функции также участвуют в разрешении перегрузки и вызывают ошибку, если они точно совпадают.
- В настоящее время у меня есть решение сделать
common_work
как CRTP, т.е. тип производного класса, переданный как шаблонный аргумент, и в конструкторе пересылки отфильтровать его какenable_if<and_<work_like<T>,not_<is_same<T,Derived> > > >
. В противном случае мне придется вручную писать copy/move constructor/assign дляwork1
иstatic_cast
в явные классы базовых классов, что является ошибкой, ошибкой и опасностью обслуживания.