VC2013:绑定不编译的功能

时间:2014-09-15 06:16:05

标签: c++ visual-c++ c++11 visual-studio-2013

这是一个简短的样本:

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;评论是)。

1 个答案:

答案 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)

Demo

也就是说,如果您将bind返回的内容传递给bind作为要绑定的参数,那么最终会传递给您绑定的函数的结果是结果调用该绑定表达式。它是一种组合。

但是,在您的代码中,您实际上并不希望合成发生。 (当我试图在fn_gg上调用你的A时,这个组合导致g ++发出320多行错误。幸运的是,使用libc ++只打印10行,谢天谢地。)你想要{{1}被对待就像一个普通的论点。所以你可以将它包装在fn_g

std::function