我有一个包含三个类(A、B 和 C)的类层次结构。A 和 B 是基类,使用派生类型进行参数化。C类派生自A和B。
using super::operator=
B 类为 A 类型的对象提供了一个赋值运算符,而 C 类通过声明继承了这个赋值运算符。
当我从 A 类型的对象定义类 B 中的构造函数时,我得到错误: 两个重载在 Visual Studio 2013 中具有相似的转换(C2666),但在 gcc (4.8.2) 中没有任何错误或警告、clang (3.4) 和英特尔 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 类中的复制赋值运算符。有人可以向我解释一下,为什么这应该是一个问题?