调用boost :: variant中类型的通用方法

时间:2012-06-20 00:19:14

标签: c++ generic-programming visitor-pattern boost-variant

如果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可能是在这里实现我自己的访问者机制的更好的替代方案。是吗?

2 个答案:

答案 0 :(得分: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 );

或类似的东西 - 我的函数指针语法错误,但希望你能理解。

答案 1 :(得分: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)支持。