[bind] Boost.Bind compile error with msvc-11 and msvc-10

I have attached a short, self-contained test case that uses Boost.Bind. this test case compiles and runs correctly with the following tool sets: darwin (gcc 4.2.1 on MacOS 10.8) clang (clang on MacOS 10.8) gcc (gcc 4.7 on Ubuntu 12.04) msvc-9 (Visual Studio 2008 on Windows 7) It fails to compile on these: msvc-11 (Visual Studio 2012 on Windows 7) msvc-10 (Visual Studio 2010 on Windows 7) I have also attached the error messages from msvc-11, which seem to indicate that Boost.Bind is the problem. Can anyone shed any light on this issue? Is this an error in my usage of Boost.Bind? A Boost.Bind bug? A Visual Studio bug? Something else? Thanks, Ian

On Feb 13, 2013, at 5:36 AM, Ian Emmons <iemmons@bbn.com> wrote:
This could be relevant: http://stackoverflow.com/questions/14837603/stdbind-on-a-vector-of-stdfuncti... -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

Ian Emmons wrote:
The problem is that vector<>::push_back is overloaded in C++11 to take an rvalue reference, and bind generally doesn't work with overloaded functions (although boost::bind does if they differ in their number of parameters, which is unfortunately not the case here). If you ignore all the "expects X parameters" errors, this is the relevant one: ATestCase.cpp(36) : error C2784: 'boost::_bi::bind_t<Rt2,boost::_mfi::cmf0<R,T>,_bi::list_av_1<A1>::type> boost::bind(boost::type<T>,R (__cdecl T::* )(void) const,A1)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' Fixing this is not particularly elegant. To select an overload, you need to do something like void (X::StringList::*pmf)(string const&) = &X::StringList::push_back; x.enumerateStrings(::boost::bind(pmf, &strList, _1)); (You'll get the same error with g++ if you use -std=c++11, by the way.)

[Peter Dimov]
Technically, taking the address of most Standard Library member functions can't be done portably. N3485 17.6.5.5 [member.functions] permits implementations to add overloads (so &foo::bar is ambiguous without additional type information) and to add default arguments (affecting the signature, so you can't provide additional type information). STL

Ian Emmons wrote:
Peter and Stephan, thanks for the information. It looks like I should write my own functor rather than use Boost.Bind in this case.
You could still use bind with your own functor, if you like. :-) struct my_push_back { template<class C, class T> void operator()( C & c, T & v ) const { c.push_back( v ); } }; and then boost::bind( my_push_back(), boost::ref( strList ), _1 );

I find Boost.Phoenix really useful in cases like this, because it comes with out-of-the-box support for lazy wrappers for STL functions: #include <boost/phoenix/core.hpp> #include <boost/phoenix/stl.hpp> ... using boost::phoenix::arg_names::_1; ... x.enumerateStrings(phoenix::push_back(phoenix::ref(strList), _1)); Full example attached. I don't have MSVC handy to try it out, but it compiles with GCC, and it solves the problem that was causing your example to fail to compile, so it should work. Regards, Nate
participants (6)
-
gast128
-
Ian Emmons
-
Marshall Clow
-
Nathan Ridge
-
Peter Dimov
-
Stephan T. Lavavej