3 つのクラス (A、B、C) を持つクラス階層があります。A と B は、派生した Type でパラメーター化された基本クラスです。クラス C は、A と B の両方から派生します。
クラス B は型 A のオブジェクトの代入演算子を提供し、クラス C はこの代入演算子をusing super::operator=
宣言と共に継承します。
タイプ A のオブジェクトからクラス B でコンストラクターを定義すると、Visual Studio 2013 でエラー: 2 つのオーバーロードが同様の変換を持っています(C2666) が表示されますが、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 でもエラーなしでコンパイルされますが、これは解決できる方法ではありません。
私の質問は次のとおりです。この構成は、標準に準拠しているという意味で整形式ですか、それともエラーメッセージは正しいですか? B のコピー コンストラクターのような指定子はexplicit
、問題の解決に役立ちますか?
ところで、Visual Studio では、クラス C のコピー代入演算子が原因で、警告:複数の代入演算子が指定されました (C4522) が表示されます。