Re: [Boost-users] boost bind, issue moving from 1.57 to 1.60
We worked around this failure by changing: Func = boost::bind(Func, _1) && boost::bind(&Boom::Oops, _1); to Func = boost::bind(AND, Func, &Boom::Oops, _1); // custom AND function Not sure why it used to work, or why it still works with raw pointers, but not shared_ptr. The actual change happens from 1.59 (working) to 1.60 (changed behavior). Jason
On Thu, Jun 16, 2016 at 3:08 PM, Jason Mancini
We worked around this failure by changing:
Func = boost::bind(Func, _1) && boost::bind(&Boom::Oops, _1);
I'm not sure why you would want to "&&" a bind result. I'm not exactly sure what it returns, something pretty close to boost::function, I would imagine, not a bool. Generally bind is useful for "callable things"; functions, functors (function objects), and so on.
to
Func = boost::bind(AND, Func, &Boom::Oops, _1); // custom AND function
Share more of the context what it is you are actually doing here. This sounds more like a promise/futures, potentially, than a bound function.
Not sure why it used to work, or why it still works with raw pointers, but not shared_ptr. The actual change happens from 1.59 (working) to 1.60 (changed behavior).
Jason
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Share more of the context what it is you are actually doing here. This sounds more like a promise/futures, potentially, than a bound function.
See this message, it's a very short test case! http://lists.boost.org/boost-users/2016/06/86248.php Jason
On Thu, Jun 16, 2016 at 4:08 PM, Jason Mancini
Share more of the context what it is you are actually doing here. This sounds more like a promise/futures, potentially, than a bound function.
See this message, it's a very short test case!
Again, bind is there to BIND to a callable thing (function or functor). Why you would want to try to LOGICAL AND the result, is beyond me.
http://lists.boost.org/boost-users/2016/06/86248.php
Jason
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Again, bind is there to BIND to a callable thing (function or functor).
Why you would want to try to LOGICAL AND the result, is beyond me.
It's not logically anding the binds right there on the spot. Each bind results in a boost::function, and &&'ing to of those results in another boost::function. It actually builds an expression which later calls both, then ands. Can I ask, are you one of the boost::bind maintainers? I'm guessing it may be best to simply file a bug report. The test case is clearly succinct. Jason
On Thu, Jun 16, 2016 at 4:50 PM, Jason Mancini
Again, bind is there to BIND to a callable thing (function or functor).
Why you would want to try to LOGICAL AND the result, is beyond me.
It's not logically anding the binds right there on the spot. Each bind results in a boost::function, and &&'ing to of those results in another boost::function. It actually builds an expression which later calls both, then ands. Can I ask, are you one of the boost::bind maintainers? I'm guessing it may be best to simply file a bug report. The test case is clearly succinct.
I'm a user, but I've never seen a usage like this before. I know you can do things like auto bound = std::bind(...), and then call the bound(...) thing later. But did not know about the logical expression.
Jason
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I'm a user, but I've never seen a usage like this before.
So this snippet comes from a sizable code base. Took a long time to pinpoint then distill the issue down to the 6-line example! Pretty sure that std::bind / std::function don't support this usage, or at least it didn't work when I tried for a few minutes. Boost flavor seems a bit more featured. The actual offender is the bigger change in bind/bind.hpp from 1.59 to 1.60 (not the trivial changes in args or placeholder). I can see they added significant std::forward / rvalue support. If I set BOOST_NO_CXX11_RVALUE_REFERENCES then also it continues to work. I suspect we've hit a corner case issue with forward / rvalue and boost::function / boost::shared_ptr. Jason
On Thu, Jun 16, 2016 at 5:39 PM, Jason Mancini
I'm a user, but I've never seen a usage like this before.
So this snippet comes from a sizable code base. Took a long time to pinpoint then distill the issue down to the 6-line example! Pretty sure that std::bind / std::function don't support this usage, or at least it didn't work when I tried for a few minutes. Boost flavor seems a bit more featured.
The actual offender is the bigger change in bind/bind.hpp from 1.59 to 1.60 (not the trivial changes in args or placeholder). I can see they added significant std::forward / rvalue support. If I set BOOST_NO_CXX11_RVALUE_REFERENCES then also it continues to work. I suspect we've hit a corner case issue with forward / rvalue and boost::function / boost::shared_ptr.
I did some work around tasking, promises, futures, a little while back, and I seem to recall some questionable things in the perfect forwarding support, but I can't recall if it was along similar lines. HTH
Jason
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 17/06/2016 09:39, Jason Mancini wrote:
So this snippet comes from a sizable code base. Took a long time to pinpoint then distill the issue down to the 6-line example! Pretty sure that std::bind / std::function don't support this usage, or at least it didn't work when I tried for a few minutes. Boost flavor seems a bit more featured.
Yeah, boost::bind supports quite a few late-binding operators, which are handy to improve code brevity but can be a bit confusing to read. If you're using a C++11 compiler then it's probably better to use lambdas for these cases now.
The actual offender is the bigger change in bind/bind.hpp from 1.59 to 1.60 (not the trivial changes in args or placeholder). I can see they added significant std::forward / rvalue support. If I set BOOST_NO_CXX11_RVALUE_REFERENCES then also it continues to work. I suspect we've hit a corner case issue with forward / rvalue and boost::function / boost::shared_ptr.
Most likely, somewhere along the way it's moving the pointer and then returning the original instead of the new one.
Under Visual Studio C++ 2013 the example works fine after adding a
reference in function signature:
boost::function
On 17/06/2016 09:39, Jason Mancini wrote:
So this snippet comes from a sizable code base. Took a long time to pinpoint then distill the issue down to the 6-line example! Pretty sure that std::bind / std::function don't support this usage, or at least it didn't work when I tried for a few minutes. Boost flavor seems a bit more featured.
Yeah, boost::bind supports quite a few late-binding operators, which are handy to improve code brevity but can be a bit confusing to read. If you're using a C++11 compiler then it's probably better to use lambdas for these cases now.
The actual offender is the bigger change in bind/bind.hpp from 1.59 to
1.60 (not the trivial changes in args or placeholder). I can see they added significant std::forward / rvalue support. If I set BOOST_NO_CXX11_RVALUE_REFERENCES then also it continues to work. I suspect we've hit a corner case issue with forward / rvalue and boost::function / boost::shared_ptr.
Most likely, somewhere along the way it's moving the pointer and then returning the original instead of the new one.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 17/06/2016 12:27, Piotr Kowalski wrote:
Under Visual Studio C++ 2013 the example works fine after adding a reference in function signature: boost::function
This somehow prevents too much forwarding and losing the original value
I'm a firm believer in never ever passing smart pointers by value -- they're still objects and copying them is expensive and unnecessary when accepting parameters. (You do have to pay for copying sometimes, particularly when passing things between threads or deferred calls -- but in this case the bind itself will do the copy and you don't need to copy it again when calling the bound method.) Although it should be a const& parameter.
Most likely, somewhere along the way it's moving the pointer and then returning the original instead of the new one.
boost::function
This somehow prevents too much forwarding and losing the original value
Ahhh yes now it all makes sense. And why raw pointer still worked. Thank you!!! That's just ... pure evil. Not the principle of least surprise! Jason
participants (4)
-
Gavin Lambert
-
Jason Mancini
-
Michael Powell
-
Piotr Kowalski