1

This code compiles fine with GCC and Clang but not with MSVC 2010:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/function.hpp>
#include <list>
#include <string>

enum Actions {};
std::string eventStart(size_t index, Actions action, std::list<std::string> const& = std::list<std::string>()) { return ""; }

static void test() {
    using namespace boost::lambda;
    size_t i = 0;
    int action = 0;
    boost::function<std::string (std::list<std::string> const&)> startF = bind(eventStart, i, (Actions)action, _1);
}

gives the error:

1>c:\users\albert zeyer\documents\visual studio 2010\projects\test\test\test2.cpp(14): error C2383: 'T0': Für dieses Symbol sind Standardargumente nicht zulässig
1>          c:\users\albert zeyer\documents\visual studio 2010\projects\test\test\test2.cpp(14): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "boost::lambda::detail::bind_tuple_mapper<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>".
1>          with
1>          [
1>              T0=std::string (size_t,Actions,const std::list<std::string> &),
1>              T1=const size_t,
1>              T2=const Actions,
1>              T3=boost::lambda::placeholder1_type,
1>              T4=boost::tuples::null_type,
1>              T5=boost::tuples::null_type,
1>              T6=boost::tuples::null_type,
1>              T7=boost::tuples::null_type,
1>              T8=boost::tuples::null_type,
1>              T9=boost::tuples::null_type
1>          ]
1>c:\users\albert zeyer\documents\visual studio 2010\projects\test\test\test2.cpp(14): error C2383: 'Arg1': Für dieses Symbol sind Standardargumente nicht zulässig

(off topic: how can I get the error in English?)

Using &eventStart instead also doesn't work but the error is different:

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxcallfun(7): error C2664: 'std::string (size_t,Actions,const std::list<_Ty> &)': Konvertierung des Parameters 3 von 'const boost::lambda::placeholder1_type' in 'const std::list<_Ty> &' nicht möglich
1>          with
1>          [
1>              _Ty=std::string
1>          ]
1>          Ursache: Konvertierung von 'const boost::lambda::placeholder1_type' in 'const std::list<_Ty>' nicht möglich
1>          with
1>          [
1>              _Ty=std::string
1>          ]
1>          Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxbind1(292): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_Ret std::tr1::_Callable_fun<_Ty,_Indirect>::_ApplyX<_Ret,_Arg&,Actions&,boost::lambda::lambda_functor<T>&>(_Arg0,_Arg1,_Arg2) const".
1>          with
1>          [
1>              _Ret=_Rx,
1>              _Ty=std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),
1>              _Indirect=false,
1>              _Arg=size_t,
1>              T=boost::lambda::placeholder<1>,
1>              _Arg0=size_t &,
1>              _Arg1=Actions &,
1>              _Arg2=const boost::lambda::placeholder1_type &
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxbind0(31): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_Ret std::tr1::_Bind3<_Callable,_Arg0,_Arg1,_Arg2>::_ApplyX<_Rx,const std::list<_Ty>&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&>(_Barg0,_Barg1,_Barg2,_Barg3,_Barg4,_Barg5,_Barg6,_Barg7,_Barg8,_Barg9)".
1>          with
1>          [
1>              _Ret=_Rx,
1>              _Callable=std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,
1>              _Arg0=size_t,
1>              _Arg1=Actions,
1>              _Arg2=const boost::lambda::placeholder1_type,
1>              _Ty=std::string,
1>              _Barg0=const std::list<std::string> &,
1>              _Barg1=std::tr1::_Nil &,
1>              _Barg2=std::tr1::_Nil &,
1>              _Barg3=std::tr1::_Nil &,
1>              _Barg4=std::tr1::_Nil &,
1>              _Barg5=std::tr1::_Nil &,
1>              _Barg6=std::tr1::_Nil &,
1>              _Barg7=std::tr1::_Nil &,
1>              _Barg8=std::tr1::_Nil &,
1>              _Barg9=std::tr1::_Nil &
1>          ]
1>          c:\program files (x86)\boost\boost_1_47\boost\function\function_template.hpp(132): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "std::basic_string<_Elem,_Traits,_Ax> std::tr1::_Bind_base<_Ret,_BindN>::operator ()<const std::list<_Ty>&>(_Carg0)".
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>,
1>              _Ret=std::string,
1>              _BindN=std::tr1::_Bind3<std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,size_t,Actions,const boost::lambda::placeholder1_type>,
1>              _Ty=std::string,
1>              _Carg0=const std::list<std::string> &
1>          ]
1>          c:\program files (x86)\boost\boost_1_47\boost\function\function_template.hpp(126): Bei der Kompilierung der  Klassen-template der std::string boost::detail::function::function_obj_invoker1<FunctionObj,R,T0>::invoke(boost::detail::function::function_buffer &,T0)-Memberfunktion
1>          with
1>          [
1>              FunctionObj=std::tr1::_Bind<std::string,std::string,std::tr1::_Bind3<std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,size_t,Actions,const boost::lambda::placeholder1_type>>,
1>              R=std::string,
1>              T0=const std::list<std::string> 
1>          ]
1>          c:\program files (x86)\boost\boost_1_47\boost\function\function_template.hpp(907): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "boost::detail::function::function_obj_invoker1<FunctionObj,R,T0>".
1>          with
1>          [
1>              FunctionObj=std::tr1::_Bind<std::string,std::string,std::tr1::_Bind3<std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,size_t,Actions,const boost::lambda::placeholder1_type>>,
1>              R=std::string,
1>              T0=const std::list<std::string> 
1>          ]
1>          c:\program files (x86)\boost\boost_1_47\boost\function\function_template.hpp(722): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void boost::function1<R,T0>::assign_to<Functor>(Functor)".
1>          with
1>          [
1>              R=std::string,
1>              T0=const std::list<std::string> ,
1>              Functor=std::tr1::_Bind<std::string,std::string,std::tr1::_Bind3<std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,size_t,Actions,const boost::lambda::placeholder1_type>>
1>          ]
1>          c:\program files (x86)\boost\boost_1_47\boost\function\function_template.hpp(1043): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "boost::function1<R,T0>::function1<std::tr1::_Bind<_Result_type,_Ret,_BindN>>(Functor,int)".
1>          with
1>          [
1>              R=std::string,
1>              T0=const std::list<std::string> ,
1>              _Result_type=std::string,
1>              _Ret=std::string,
1>              _BindN=std::tr1::_Bind3<std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,size_t,Actions,const boost::lambda::placeholder1_type>,
1>              Functor=std::tr1::_Bind<std::string,std::string,std::tr1::_Bind3<std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,size_t,Actions,const boost::lambda::placeholder1_type>>
1>          ]
1>          c:\users\albert zeyer\documents\visual studio 2010\projects\test\test\test2.cpp(14): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "boost::function<Signature>::function<std::tr1::_Bind<_Result_type,_Ret,_BindN>>(Functor,int)".
1>          with
1>          [
1>              Signature=std::string (const std::list<std::string> &),
1>              _Result_type=std::string,
1>              _Ret=std::string,
1>              _BindN=std::tr1::_Bind3<std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,size_t,Actions,const boost::lambda::placeholder1_type>,
1>              Functor=std::tr1::_Bind<std::string,std::string,std::tr1::_Bind3<std::tr1::_Callable_fun<std::string (__cdecl *const )(size_t,Actions,const std::list<std::string> &),false>,size_t,Actions,const boost::lambda::placeholder1_type>>
1>          ]

Why? The code seems correct.

It works when I remove the default argument for the eventStart function.

Albert
  • 65,406
  • 61
  • 242
  • 386
  • A trivial workaround is to do `bind(&eventStart, ...)` rather than `bind(eventStart, ...)`, but I don't know why this is necessary (or if it's necessary at all on a conformant compiler). Also, you should be using [Boost.Phoenix](http://www.boost.org/libs/phoenix/) rather than Boost.Lambda for new code, as the latter is considered officially deprecated in favor of the former. – ildjarn Mar 29 '12 at 20:02
  • @ildjarn: Also doesn't work. I updated the question. – Albert Mar 29 '12 at 20:06
  • It works for me, testing with VC++ 2010 SP1 and Boost 1.49.0. – ildjarn Mar 29 '12 at 20:06
  • @ildjarn: Where is it said that Boost.Lambda is deprecated? – Albert Mar 29 '12 at 20:10
  • It's not in the official documentation yet (because the Boost.Lambda maintainer is absent and cannot update it), but it's been posted many times over on the Boost.Dev mailing list. – ildjarn Mar 29 '12 at 20:11
  • with MSVC10 you can just use `std::function` and `std::bind` ... – AJG85 Mar 29 '12 at 21:27
  • @AJG85: It should be cross-platform and work on any pre-C++11 compatible compiler, so that is not an option. – Albert Mar 29 '12 at 21:35
  • @Albert I don't use boost anymore so it's not as convenient to test but GCC had this before 4.7 as well and that's been released. You can get the error message in English by compiling boost with that locale probably, or read the German? – AJG85 Mar 29 '12 at 21:37
  • @AJG85: The error message is from MSVC, not from Boost. And I don't want to (and can't) restrict the code to GCC 4.7 / MSVC 2010. – Albert Mar 29 '12 at 21:42

1 Answers1

1

As ildjarn suggested, I use &eventStart instead of eventStart. That alone didn't yet work for me.

But when I change bind to boost::lambda::bind, it works.

This is strange however because there is no using namespace std; or so.

Albert
  • 65,406
  • 61
  • 242
  • 386
  • @MichaelBurr: Hm, interesting. Exactly the same test code from my question? And also using `&eventStart` instead of `eventStart`. What MSVC version do you use? – Albert Mar 31 '12 at 13:55
  • if I use *both* `boost::lambda::bind` and `&eventStart` it compiles. I guess I didn't try that before. I'm running VS2010 SP1 (10.0.40219.1 SP1Rel) which has cl.exe version 16.00.40219.01. – Michael Burr Mar 31 '12 at 18:20