Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VC2013: function from bind not compiling

Here is a short sample:

class A {};

class S {};

class B
{
public:
    typedef std::function <bool (A& retVal)> property_getter_t;
    typedef std::function<bool (B* /*this*/, const std::shared_ptr<S>&, A& retVal)> SettingsPropGetter;

    void DefineSettingsProperty(const std::wstring& name, const SettingsPropGetter& getter)
    {
        auto fn_g = std::bind(getter, this, std::placeholders::_1, std::placeholders::_2);
        auto fn_gg = std::bind(&B::GetterHandler, this, fn_g, std::placeholders::_1);

        property_getter_t x = fn_gg;  // PROBLEM IS HERE
    }

    bool GetterHandler(const std::function<bool (const std::shared_ptr<S>&, A&)>& getter, A& a)
    {
        std::shared_ptr <S> s;
        return getter (s, a);
    }
};

The code compiles fine under VC2010. Under VC2013 I keep getting a huge pack of errors.

What's wrong? Can this be fixed somehow?

Here are the errors:

1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\tuple(540): error C2504: 'std::tuple_element<0,std::tuple<>>' : base class undefined
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(900) : see reference to class template instantiation 'std::tuple_element<1,_Ftuple>' being compiled
1>          with
1>          [
1>              _Ftuple=std::tuple<A &>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(946) : see reference to class template instantiation 'std::_Fixarg_ret_base<_Placeholder,_Funx,std::_Ph<2>,_Ftuple>' being compiled
1>          with
1>          [
1>              _Funx=std::function<bool (B *,const std::shared_ptr<S> &,A &)>
1>  ,            _Ftuple=std::tuple<A &>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(975) : see reference to class template instantiation 'std::_Fixarg_ret<_Funx,std::_Ph<2> &,_Ftuple>' being compiled
1>          with
1>          [
1>              _Funx=std::function<bool (B *,const std::shared_ptr<S> &,A &)>
1>  ,            _Ftuple=std::tuple<A &>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(58) : see reference to class template instantiation 'std::_Do_call_ret<false,_Ret,std::function<bool (B *,const std::shared_ptr<S> &,A &)>,std::tuple<B *,std::_Ph<1>,std::_Ph<2>>,std::tuple<A &>,std::_Arg_idx<0,1,2>>' being compiled
1>          with
1>          [
1>              _Ret=void
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(118) : see reference to class template instantiation 'std::_Result_of<_Fty,A &>' being compiled
1>          with
1>          [
1>              _Fty=std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(914) : see reference to class template instantiation 'std::result_of<_Bind_t (A &)>' being compiled
1>          with
1>          [
1>              _Bind_t=std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(924) : see reference to class template instantiation 'std::_Call_ret<_Barg,std::tuple<A &>,std::_Arg_idx<0>>' being compiled
1>          with
1>          [
1>              _Barg=std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(946) : see reference to class template instantiation 'std::_Fixarg_ret_base<_Bind_expression,_Funx,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &>,_Ftuple>' being compiled
1>          with
1>          [
1>              _Funx=std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &> &
1>  ,            _Ftuple=std::tuple<A &>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1148) : see reference to class template instantiation 'std::_Fixarg_ret<std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &> &,_Ty,std::tuple<A &>>' being compiled
1>          with
1>          [
1>              _Ty=std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'bool std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>::_Do_call<A,0,1,2>(std::tuple<A &>,std::_Arg_idx<0,1,2>)' being compiled
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'bool std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>::_Do_call<A,0,1,2>(std::tuple<A &>,std::_Arg_idx<0,1,2>)' being compiled
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(283) : see reference to function template instantiation 'bool std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>::operator ()<A&>(A &)' being compiled
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(283) : see reference to function template instantiation 'bool std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>::operator ()<A&>(A &)' being compiled
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<std::_Bind<true,_Ret,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>,false>::_ApplyX<_Rx,A&>(A &)' being compiled
1>          with
1>          [
1>              _Ret=bool
1>  ,            _Rx=bool
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<std::_Bind<true,_Ret,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>,false>::_ApplyX<_Rx,A&>(A &)' being compiled
1>          with
1>          [
1>              _Ret=bool
1>  ,            _Rx=bool
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(226) : while compiling class template member function 'bool std::_Func_impl<_MyWrapper,_Alloc,_Ret,A &>::_Do_call(A &)'
1>          with
1>          [
1>              _Alloc=std::allocator<std::_Func_class<bool,A &>>
1>  ,            _Ret=bool
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(495) : see reference to class template instantiation 'std::_Func_impl<_MyWrapper,_Alloc,_Ret,A &>' being compiled
1>          with
1>          [
1>              _Alloc=std::allocator<std::_Func_class<bool,A &>>
1>  ,            _Ret=bool
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,A &>::_Do_alloc<_Myimpl,std::_Bind<true,_Ret,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>&,_Alloc>(_Fty,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=bool
1>  ,            _Alloc=std::allocator<std::_Func_class<bool,A &>>
1>  ,            _Fty=std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &> &
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,A &>::_Do_alloc<_Myimpl,std::_Bind<true,_Ret,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>&,_Alloc>(_Fty,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=bool
1>  ,            _Alloc=std::allocator<std::_Func_class<bool,A &>>
1>  ,            _Fty=std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &> &
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,A &>::_Reset_alloc<std::_Bind<true,_Ret,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>&,std::allocator<std::_Func_class<_Ret,A &>>>(_Fty,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=bool
1>  ,            _Fty=std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &> &
1>  ,            _Alloc=std::allocator<std::_Func_class<bool,A &>>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,A &>::_Reset_alloc<std::_Bind<true,_Ret,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>&,std::allocator<std::_Func_class<_Ret,A &>>>(_Fty,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=bool
1>  ,            _Fty=std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &> &
1>  ,            _Alloc=std::allocator<std::_Func_class<bool,A &>>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,A &>::_Reset<std::_Bind<true,_Ret,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>&>(_Fty)' being compiled
1>          with
1>          [
1>              _Ret=bool
1>  ,            _Fty=std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &> &
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,A &>::_Reset<std::_Bind<true,_Ret,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>&>(_Fty)' being compiled
1>          with
1>          [
1>              _Ret=bool
1>  ,            _Fty=std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &> &
1>          ]
1>          c:\work\source\test.cpp(29) : see reference to function template instantiation 'std::function<bool (A &)>::function<std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>&>(_Fx)' being compiled
1>          with
1>          [
1>              _Fx=std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &> &
1>          ]
1>          c:\work\source\test.cpp(29) : see reference to function template instantiation 'std::function<bool (A &)>::function<std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &>&>(_Fx)' being compiled
1>          with
1>          [
1>              _Fx=std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall B::* )(const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &),bool,B,const std::function<bool (const std::shared_ptr<S> &,A &)> &,A &>,B *const ,std::_Bind<false,void,const B::SettingsPropGetter &,B *const ,std::_Ph<1> &,std::_Ph<2> &> &,std::_Ph<1> &> &
1>          ]
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(900): error C2039: 'type' : is not a member of 'std::tuple_element<1,_Ftuple>'
1>          with
1>          [
1>              _Ftuple=std::tuple<A &>
1>          ]
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(900): error C2146: syntax error : missing ',' before identifier 'type'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(900): error C2065: 'type' : undeclared identifier
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(900): error C2977: 'std::add_reference' : too many template arguments
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(180) : see declaration of 'std::add_reference'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(900): error C2955: 'std::add_reference' : use of class template requires template argument list
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(180) : see declaration of 'std::add_reference'

c:\work\source\test.cpp(29) - is my source file (where the "PROBLEM IS HERE" comment is).

like image 506
Alexander Dyagilev Avatar asked Aug 31 '26 08:08

Alexander Dyagilev


1 Answers

I would normally quote the standard, but the standardese here is particularly dense, so I'll just explain what's happening.

std::bind does something special when you pass an argument to be bound if that argument is a function object returned by a previous call to std::bind. Suppose you do:

auto f = std::bind(foo, std::placeholders::_1);
auto g = std::bind(bar, f, std::placeholders::_1);

Then invoking g(a) is roughly equivalent to

bar(foo(a), a)

rather than

bar(f, a)

Demo.

That is, if you pass something returned by bind to bind as an argument to be bound, what's going to end up being passed to the function you are binding is the result of invoking that bind expression. It's a sort of composition.

However, in your code, you actually don't want the composition to take place. (This composition is what caused g++ to emit 320+ lines of errors when I tried to call your fn_gg on an A. Clang with libc++ printed only 10 lines, thankfully.) You want fn_g to be treated just like an ordinary argument. So you can wrap it in a std::function:

std::function<bool (const std::shared_ptr<S>&, A&)> fn_g = std::bind(getter, this, std::placeholders::_1, std::placeholders::_2);
like image 76
T.C. Avatar answered Sep 02 '26 05:09

T.C.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!