Re: [Boost-users] [RFC] Signals bound to phoenix functions

On Thursday 24 June 2010 09:31:36 Thomas Heller wrote:
On Wednesday 23 June 2010 18:50:38 Ovanes Markarian wrote:
Stephan, hi!
please see my answer below.
On Wed, Jun 23, 2010 at 5:42 PM, Stephan Menzel
<stephan.menzel@gmail.com>wrote:
Unless I want to add something. Unfortunately I can't always take wrap()s output but have to modify a little. In fact, my Queue needs to be templatized as well, modifying the behaviour of the functor. I have a template parameter "Calling". When it is true, another function shall be called by the functor after the method was posted. Now I wanted to do this by phoenix:
template <bool Calling> class Queue {
template<typename Handler>
void post(Handler n_handler) {
m_iosrv.post(n_handler);
};
...
template<typename SlotSignature, typename SlotFunction> boost::signals2::connection
connect(boost::signals2::signal<SlotSignature> &n_signal, SlotFunction n_method) {
return n_signal.connect(
if_( CallingBack ) [
post(n_method) , m_signal_callback()
] .else_ [
m_iosrv.wrap( n_method )
] );
};
...
It is difficult to conclude smth from the code without having a self-containing example. But my assumption is that in the 'else'-branch your code does not generate a function object. As far as I can see in the 'if'-branch your code generates a function object using the the comma-operator (if that operator is overloaded in Phoenix), in the 'else'-branch you just have a normal function call, which is not lazy and does not return a function-object.
Phoenix statements always return void. What you want is: phoenix::if_else( CallingBack, /* then functor */, /*else functor */ )
For reference: http://www.boost.org/doc/libs/1_43_0/libs/spirit/phoenix/doc/html/phoenix/c omposite.html#phoenix.composite.operator and http://www.boost.org/doc/libs/1_43_0/libs/spirit/phoenix/doc/html/phoenix/c omposite.html#phoenix.composite.statement (There is a note at the end of that section, for the return value of phoenix statements)
Sorry misunderstood your problem ... The correct answer is: post, m_signal_callback() and m_iosrv.wrap need to be lazy expressions. To achieve that for the first two, you can have a phoenix::function wrapper, for the last one, you can use phoenix::bind (which can be used for the first two as well).

Hi Thomas, On Thu, Jun 24, 2010 at 11:20 AM, Thomas Heller <thom.heller@googlemail.com> wrote:
The correct answer is: post, m_signal_callback() and m_iosrv.wrap need to be lazy expressions. To achieve that for the first two, you can have a phoenix::function wrapper, for the last one, you can use phoenix::bind (which can be used for the first two as well).
I went for a lazy expression in the meantime, with moderate success. It works for void() handlers, but as soon as multiple parameters kick in the originally bound method appears to need additional binding. I'll have a sample attached. Here's the lazy function template <bool CallingBack> struct slot_wrap_impl { public: slot_wrap_impl(Queue<CallingBack> &n_q) : m_q(n_q) {}; template <typename SlotSignature> struct result { typedef void type; }; template <typename SlotSignature> typename result<SlotSignature>::type operator()(SlotSignature n_method) const { using boost::phoenix::if_; using boost::phoenix::switch_; using boost::phoenix::case_; using boost::phoenix::default_; using boost::phoenix::bind; std::cout << "binding post...\n"; m_q.post(n_method); // X std::cout << "post bound" << std::endl; /* if (CallingBack) { m_q.callback(); }; */ }; private: Queue<CallingBack> &m_q; }; I call this in my connector using: boost::phoenix::function<slot_wrap_impl<CallingBack> > f(*this); boost::signals2::connection ret = n_signal.connect(f(n_method)); return ret; I think I'm finally on my way to get it. Everything is executed the way it should be. The main problem that remains is: Why is the lazy function unable to call post() with something different than function<void()> as an argument? The calling party already uses bind on the function and the lazy function should only see void() no matter what comes in. If I could solve this, the problem would be gone. I tried to determine arity and then use placeholders but I doubt this is ever going to compile, let alone work. Does any of this make sense or am I fooled by an accidentally working but broken thing? Cheers, Stephan
participants (2)
-
Stephan Menzel
-
Thomas Heller