Calling methods common to types in a boost::variant
-
15-06-2021 - |
質問
If all the types in my boost::variant
support the same method, is there a way to call it generically (i.e. not calling it seperately for each method of the static_visitor
)?
I'm trying to get something like this to work:
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();
}
but it fails to compile saying 'boo' : is not a member of 'boost::variant<T0_,T1,T2>'
.
Currently, I have some classes all inherit from an interface so that their single shared method can be used polymorphically. I also want to be able to use the classes via a visitor as all other methods are unique to each concrete class. I was hoping boost::variant
might be a better alternative to implementing my own visitor mechanism here. Is it?
解決
There's no direct way, but you can make the static_visitor pretty concise using templating.
Modified from the boost docs:
struct boo_generic : public boost::static_visitor<>
{
template <typename T>
void operator()( T & operand ) const
{
operand.boo();
}
};
Now you can do this:
boost::apply_visitor( boo_generic(), v );
Infact you can generalise this to take a function pointer of your base class:
struct fn_generic : public boost::static_visitor<>
{
fn_generic( void (IBase::fn)() ) : fn_(fn) {}
template<T> void operator() ( T & op ) const { op.*fn(); }
}
Then you can do:
boost::apply_visitor( boo_generic( IBase::boo ), v );
Or something like that - I've probably got my function pointer syntax wrong, but hopefully you get the idea.
他のヒント
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();
}
Won't boost::relaxed_get
work in the example above?
Note: this required Real Time Type Information (RTTI) support.