1

実用的な理由で、私は次のようなクラスを持っています

template <class A>
class CRTP
{
    template <int (A::*Member)()>
    int func(void * obj)
    {
        int result
        // Do something with Member, like
        // result = (reinterpret_cast<A*>(obj)->*Member)();
        return result;
    }
};

これtemplate <void (A::*Member)()>は要件であり、引数として渡すことはできません。

そして私はクラスベースも持っています

class Base : public CRTP<Base>
{
    int aMemberOfBase() {...}
};

そして、私もCRTPを継承したいその派生物

class Derived : public CRTP<Derived>, public Base
{
    int aMemberOfDerived() {...}
};

Derivedの一部のメンバーでは、次のようなことをします

func<&Derived::aMemberOfDerived>(this);
func<&Base::aMemberOfBase>(this);

それは可能ですか?

(まあ、VC ++は最初の行だけをコンパイルし、2番目の行については読みたくありません...しかしDerivedにはメンバーが必要です

template <int (Base::*Member)()> int func(void * obj);
template <int (Derived::*Member)()> int func(void * obj);

奇妙に見えますが、私はそれを認めます。しかし、次のコードは

template <void (Base::*Member)()> int func() {return 0;}
template <void (Derived::*Member)()> int func() {return 1;}

func<&Base::someMember>() != func<&Derived::someMember>()テンプレートの署名は同じではなく、同じにすることはできないため、コンパイルして返します。)

私は、規格が言っていることを十分に評価していないことを認めなければなりません。しかし、私が作ろうとしている遺伝形式は許可されていますか?もしそうなら、なぜ行の1つがコンパイルされないのですか?

また、宣言すれば

class Derived : public Base, public CRTP<Derived>

それ以外の

class Derived : public CRTP<Derived>, public Base

(すべてで)コンパイル時エラーが発生しますfunc<...>(...)。これは、どこかに問題があることを意味します。

一方、私はそれを知っています

template <class A, int (A::*Member)()> int func(void * obj)

CRTPの必要性を排除しますが、書くのは苦痛func<Derived, &Derived::aMember>()です。次のような回避策はありますか

template <class Class, void (Class::*Member)()> class A 
{
    void func(void * obj) {...(reinterpret_cast<Class*>(obj)->*Member)();...} 
};
template <typename Signature> class B;

template <typename Class, typename Member>
class B<&Class::Member> : public class A<Class, &Class::Member> {};

どちらが可能になりB<&Base::Derived>().func(somePtrToBase)ますか?

4

1 に答える 1

1

基本メンバー テンプレートの名前を修飾することで、あいまいさをなくすことができます。以下が機能するはずです。

template <typename A> struct CRTP
{
    template <int (A::*Member)()> int func();
};

struct Base : CRTP<Base>
{
    int aMemberOfBase();
};

struct Derived : CRTP<Derived>, Base
{
    int aMemberOfDerived();

    void foo()
    {
        CRTP<Derived>::func<&Derived::aMemberOfDerived>();
        CRTP<Base>::func<&Base::aMemberOfBase>();
    }
};

アクセス制御の詳細に行き詰まらないように、すべてを公開しました。

于 2013-03-09T22:46:04.180 に答える