[variant] Variant call forwarding?
Hello, I'm wondering what's the easiest way to enable call forwarding by a variant to contained function objects accepting the same arguments? I.e., variant< F, G > m_funcs; m_funcs = f; m_funcs( a, b, c ); m_funcs = g; m_funcs( a, b, c ); Thanks, Cheers, Rutger
I'm wondering what's the easiest way to enable call forwarding by a variant to contained function objects accepting the same arguments?
I.e.,
variant< F, G > m_funcs;
m_funcs = f; m_funcs( a, b, c );
m_funcs = g; m_funcs( a, b, c );
If both F & G have the same signature, what's the purpose of variant?
On Tue, Feb 23, 2010 at 10:43 AM, Rutger ter Borg
Igor R wrote:
If both F & G have the same signature, what's the purpose of variant?
To be able to choose one of them at runtime :-) ... I'm looking for something similar to boost::function<>, but which doesn't erase all type information.
Heh, again, if they have the same signature, what information would you be losing? :)
To be able to choose one of them at runtime :-) ... I'm looking for something similar to boost::function<>, but which doesn't erase all type information.
Lets assume you've got 2 different functions with the same signature:
void f1(int i, double d);
void f2(int i, double d);
What do you loose by putting them into boost::function
On Tue, Feb 23, 2010 at 11:59 AM, Igor R
To be able to choose one of them at runtime :-) ... I'm looking for something similar to boost::function<>, but which doesn't erase all type information.
Lets assume you've got 2 different functions with the same signature: void f1(int i, double d); void f2(int i, double d);
What do you loose by putting them into boost::function
?
You lose the ability a) To use a function *object* which contains state b) To use different pre & post call logic depending on which function is selected. Using a variant, you can imagine it ultimately boiling down to a large "behind the scenes" if-then-else block that selects which object is to be invoked. However, instead of simply doing the invoke, variant gives you the flexibility of specifying arbitrary code to run both before and after the invocation. Also, boost::function<> has quite a high overhead compared to variant. Zach
Zachary Turner wrote:
You lose the ability
a) To use a function *object* which contains state
Is this correct? Isn't, e.g., a bind expression already a function object that contains state? Or do you mean that you loose the ability to access the state of such a function object? Thanks, Cheers, Rutger
On Fri, Feb 26, 2010 at 4:00 AM, Rutger ter Borg
Zachary Turner wrote:
You lose the ability
a) To use a function *object* which contains state
Is this correct? Isn't, e.g., a bind expression already a function object that contains state? Or do you mean that you loose the ability to access the state of such a function object?
Thanks, Cheers,
Yes, I meant accessing the state of such a function object. With arbitrary functors you can provide arbitrary state that can be modified by operator() of the visitor. After the call to apply_visitor(), you can access this state. Zach
Rutger ter Borg a écrit :
Hello,
I'm wondering what's the easiest way to enable call forwarding by a variant to contained function objects accepting the same arguments?
I.e.,
variant< F, G > m_funcs;
m_funcs = f; m_funcs( a, b, c );
m_funcs = g; m_funcs( a, b, c );
Let's consider that's the signature is R (T1, T2, T3). struct call_visitor : static_visitor<R> { call_visitor(T1&& a_, T2&& b_, T3&& c_) : a(a_), b(b_), c(c_) { } template<typename F> R operator()(F& f) const { return f(a, b, c); } T1&& a; T2&& b; T3&& c; }; Then you could do what you want with apply_visitor(call_visitor(a, b, c), m_funcs); If you want to do it for arbitrary signatures and provide perfect forwarding without rvalue references, it is going to be a bit more work. With polymorphic lambdas (an extension to C++0x lambdas), it is quite simpler: apply_visitor([&](auto& f) { return f(a, b, c); }, m_funcs);
Mathias Gaunard wrote:
If you want to do it for arbitrary signatures and provide perfect forwarding without rvalue references, it is going to be a bit more work.
Thanks, indeed. Although the amount of work is eased by using stuff like function_types and preprocessor stuff.
With polymorphic lambdas (an extension to C++0x lambdas), it is quite simpler:
apply_visitor([&](auto& f) { return f(a, b, c); }, m_funcs);
Polymorphic lambdas ... I guess you're talking C++1x here :-) Cheers, Rutger
participants (5)
-
Igor R
-
Mathias Gaunard
-
OvermindDL1
-
Rutger ter Borg
-
Zachary Turner