7

私のすべてのタイプがboost::variant同じメソッドをサポートしている場合、それを一般的に呼び出す方法はありますか(つまり、のメソッドごとに個別に呼び出さないでstatic_visitorください)?

私はこのようなものを機能させようとしています:

class A
{
    void boo() {}
};

class B
{
    void boo() {}
};

class C
{
    void boo() {}
};

typedef boost::variant<A, B, C> X;

void foo(X& d)
{
    x.boo();
}

しかし、それは言ってコンパイルに失敗します'boo' : is not a member of 'boost::variant<T0_,T1,T2>'

現在、いくつかのクラスはすべてインターフェイスから継承しているため、それらの単一の共有メソッドを多態的に使用できます。また、他のすべてのメソッドは各具象クラスに固有であるため、訪問者を介してクラスを使用できるようにしたいと思います。boost::variant私は、ここで自分の訪問者メカニズムを実装するよりも良い代替手段になることを望んでいました。それは...ですか?

4

2 に答える 2

4

直接的な方法はありませんが、テンプレートを使用してstatic_visitorをかなり簡潔にすることができます。

ブーストドキュメントから変更:

struct boo_generic : public boost::static_visitor<>
{
    template <typename T>
    void operator()( T & operand ) const
    {
        operand.boo();
    }
};

今、あなたはこれを行うことができます:

boost::apply_visitor( boo_generic(), v );

実際、これを一般化して、基本クラスの関数ポインターを取得できます。

struct fn_generic : public boost::static_visitor<>
{
   fn_generic( void (IBase::fn)() ) : fn_(fn) {}
   template<T> void operator() ( T & op ) const { op.*fn(); }
}

次に、次のことができます。

boost::apply_visitor( boo_generic( IBase::boo ), v );

またはそのようなもの-おそらく関数ポインタの構文が間違っているかもしれませんが、うまくいけばあなたはその考えを理解するでしょう。

于 2012-06-20T00:59:17.030 に答える
0
class Base {
    virtual void boo() = 0;
};

class A : Base
{
    void boo() override {}
};

class B : Base
{
    void boo() override {}
};

class C : Base
{
    void boo() override {}
};

typedef boost::variant<A, B, C> X;

void foo(X& x)
{
    boost::relaxed_get<Base>(x).boo();
}

boost::relaxed_get上記の例では機能しませんか?注:これには、リアルタイム型情報(RTTI)のサポートが必要でした。

于 2018-06-14T16:32:21.950 に答える