VC2013:来自绑定的函数未编译 [英] VC2013: function from bind not compiling

查看:13
本文介绍了VC2013:来自绑定的函数未编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简短的示例:

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 下,我不断收到大量错误.

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

怎么了?这能以某种方式修复吗?

What's wrong? Can this be fixed somehow?

以下是错误:

1>c:program files (x86)microsoft visual studio 12.0vcinclude	uple(540): error C2504: 'std::tuple_element<0,std::tuple<>>' : base class undefined
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludexrefwrap(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.0vcincludexrefwrap(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludexrefwrap(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.0vcincludexrefwrap(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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:worksource	est.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:worksource	est.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.0vcincludefunctional(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.0vcincludefunctional(900): error C2146: syntax error : missing ',' before identifier 'type'
1>c:program files (x86)microsoft visual studio 12.0vcincludefunctional(900): error C2065: 'type' : undeclared identifier
1>c:program files (x86)microsoft visual studio 12.0vcincludefunctional(900): error C2977: 'std::add_reference' : too many template arguments
1>          c:program files (x86)microsoft visual studio 12.0vcinclude	ype_traits(180) : see declaration of 'std::add_reference'
1>c:program files (x86)microsoft visual studio 12.0vcincludefunctional(900): error C2955: 'std::add_reference' : use of class template requires template argument list
1>          c:program files (x86)microsoft visual studio 12.0vcinclude	ype_traits(180) : see declaration of 'std::add_reference'

c:worksource est.cpp(29) - 是我的源文件(问题在这里"注释所在的位置).

c:worksource est.cpp(29) - is my source file (where the "PROBLEM IS HERE" comment is).

推荐答案

我通常会引用标准,但这里的标准语特别密集,所以我只会解释发生了什么.

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

std::bind 在传递要绑定的参数时会做一些特别的事情,如果该参数是先前调用 std::bind 返回的函数对象.假设你这样做:

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);

然后调用g(a)大致相当于

bar(foo(a), a)

而不是

bar(f, a)

演示.

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

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.

但是,在您的代码中,您实际上不希望组合发生.(当我尝试在 A 上调用您的 fn_gg 时,这种组合导致 g++ 发出 320 多行错误.幸好,使用 libc++ 的 Clang 仅打印了 10 行.)您希望 fn_g 被视为普通参数.所以你可以把它包装在一个 std::function:

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);

这篇关于VC2013:来自绑定的函数未编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆