У меня есть иерархия классов с тремя классами (A, B и C). A и B являются базовыми классами, параметризованными производным типом. Класс C является производным от обоих, A и B.
Класс B предоставляет оператор присваивания для объектов типа A, а класс C наследует этот оператор присваивания с объявлением using super::operator=
.
Когда я определяю конструктор в классе B из объектов типа A, я получаю Ошибку: две перегрузки имеют похожие преобразования (C2666) в Visual Studio 2013, но я не не получают никаких ошибок или предупреждений в gcc (4.8.2), clang (3.4) и intel icc (Studio 2015). (скомпилировано с -Wall -pedantic
)
Вот уменьшенный пример:
template <class Model> struct A {};
template <class Model> struct B
{
B() {}; // default constructor
// copy constructor for objects of type A
template <class M>
B(A<M> const&) {}
// assignment operator for objects of type A
template <class M>
Model& operator=(A<M> const& rhs)
{
return static_cast<Model&>(*this);
}
};
struct C : public B<C>, public A<C>
{
typedef B<C> super;
// copy assignment operator
C& operator=(C const& rhs) { return *this; }
// adopt assignment operator for A<C> from super-class
using super::operator=;
};
int main()
{
C c;
A<C> a;
c = a;
}
Если бы я заменил шаблонный класс A на нешаблонный класс, он также компилируется в Visual Studio без ошибок, но это не так, как это можно решить.
Мой вопрос: правильно ли построена эта конструкция в том смысле, что она соответствует стандарту, или сообщение об ошибке верно? Помогает ли спецификатор типа explicit
для конструктора копирования в B решить проблему?
Кстати: в Visual Studio я получаю Предупреждение: указано несколько операторов присваивания (C4522) из-за оператора присваивания копирования в классе C. Может ли кто-нибудь объяснить мне , почему это должно быть проблемой?