9

派生クラスのクローンを作成する基本クラスがあるとします。

class Base
{
    public:
        virtual Base * clone()
        {
            return new Base();
        }

        // ...
};

私は不思議なことに繰り返されるテンプレート パターンを使用して実装されている一連の派生クラスを持っています。

template <class T>
class CRTP : public Base
{
    public:
        virtual T * clone()
        {
            return new T();
        }

        // ...
};

そして、私はそれからさらに次のように導き出そうとします:

class Derived : public CRTP<Derived>
{
    public:
        // ...
};

次のようなコンパイル エラーが発生します。

error C2555: 'CRTP<T>::clone': overriding virtual function return type differs and is not covariant from 'Base::clone'

これはおそらく、コンパイラが CRTP をインスタンス化するときに Derived の継承ツリーを完全に認識していないことが原因であると認識しています。さらに、戻り値の型 (T*) を (Base*) に置き換えてもコンパイルされます。ただし、上記のセマンティクスを保持する回避策があるかどうかを知りたいです。

4

2 に答える 2

3

あまりきれいではない回避策。

class Base
{
    protected:
        virtual Base * clone_p()
        {
            return new Base();
        }
};


template <class T>
class CRTP : public Base
{
    protected:
        virtual CRTP* clone_p()
        {
            return new T;
        }
    public:
        T* clone()
        {
            CRTP* res = clone_p();
            return static_cast<T*>(res);
        }
};


class Derived : public CRTP<Derived>
{
    public:
};

安全だと思われる場合はdynamic_cast<>代わりに使用してください。static

于 2013-06-19T21:49:10.507 に答える