Мое понимание конструктора неявного копирования С++ похоже на
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)...
{}
Пример
У меня был класс, который имел неявный конструктор копирования/перемещения/оператор присваивания, а также некоторые конструкторы преобразования. Я делегировал работу какому-то классу реализации.
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
конструкторы копирования/перемещения вызывали конструктор копирования/перемещения для common_work
, а конструктор пересылки использовался другими конструкторами [не показано в коде], которые преобразуются из другого типа work
.
Тогда я думал унаследовать work1
от common_work
для EBO и других причин. Так выглядел новый класс work1
class work1 : private common_work
{
work1(work1 const& ) = default;
work1(work1&& ) = default; ...
};
Но так как work1
является классом work_like
, внезапно конструктор пересылки стал лучше соответствовать, поскольку конструктор копирования/перемещения для common_work
требует static_cast
от производного к базовому.
ПРИМЕЧАНИЕ:
- Подобный пример приводит Скотт Мейерс. , где конструкция копирования запускает конструктор пересылки, поскольку конструктор копирования требует добавления константы, а конструктор пересылки не требует. Но я думаю, что эта проблема возникает из-за неправильного дизайна класса, в то время как проблема здесь связана с тем, что аргумент, передаваемый базовому классу во время неявного копирования/перемещения, не является точным совпадением.
- Я не могу написать универсальный конструктор/назначение пересылки и удалить неявные, потому что удаленные функции также участвуют в разрешении перегрузки и вызывают ошибку при точном совпадении.
- В настоящее время решение, которое у меня есть, состоит в том, чтобы сделать
common_work
как CRTP , то есть тип производного класса, переданный в качестве аргумента шаблона, и в конструкторе пересылки отфильтровать его какenable_if<and_<work_like<T>,not_<is_same<T,Derived> > > >
. В противном случае мне придется вручную писать конструктор копирования/перемещения/назначение дляwork1
иstatic_cast
в базовые классы явно, что является ошибочным, подверженным ошибкам и опасным для обслуживания.
T
, производные отcommon_work
? - person Andy Prowl   schedule 18.07.2013is_same<T,Derived>
, аis_same<remove_ref<T>,Derived>
- person abir   schedule 18.07.2013