这是一个简短的样本:
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);
}
};
VC2010下的代码编译得很好。 在VC2013下,我不断收到大量错误。
出了什么问题?这可以以某种方式修复吗?
以下是错误:
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) - 是我的源文件(&#34;问题在这里&#34;评论是)。
答案 0 :(得分:7)
我通常引用标准,但这里的标准特别密集,所以我只是解释发生了什么。
如果该参数是前一次调用std::bind
返回的函数对象,则传递要绑定的参数时, std::bind
会执行一些特殊操作。假设您这样做:
auto f = std::bind(foo, std::placeholders::_1);
auto g = std::bind(bar, f, std::placeholders::_1);
然后调用g(a)
大致相当于
bar(foo(a), a)
而不是
bar(f, a)
也就是说,如果您将bind
返回的内容传递给bind
作为要绑定的参数,那么最终会传递给您绑定的函数的结果是结果调用该绑定表达式。它是一种组合。
但是,在您的代码中,您实际上并不希望合成发生。 (当我试图在fn_gg
上调用你的A
时,这个组合导致g ++发出320多行错误。幸运的是,使用libc ++只打印10行,谢天谢地。)你想要{{1}被对待就像一个普通的论点。所以你可以将它包装在fn_g
:
std::function