Std::bind on a vector of std::functions compiles in VC10, but not VC11. What did I do wrong?

走远了吗. 提交于 2020-01-15 15:33:14

问题


When moving from VC10 to VC11, the following code fails to compile.

#include <algorithm>
#include <functional>
#include <vector>

using namespace std;
using namespace std::placeholders;

typedef std::function<void(int)> CB;


int main()
{
    vector<CB> m_CBs;
    int m_LongPressGesture;

  for_each(m_CBs.begin(), m_CBs.end(), bind(&CB::operator(), _1, m_LongPressGesture));
    return 0;
}

The error output is illegal indirection. Here's the complete output.

1>------ Build started: Project: CompileError, Configuration: Debug Win32 ------
1>Build started 2/12/2013 4:32:56 PM.
1>InitializeBuildStatus:
1>  Touching "Debug\CompileError.unsuccessfulbuild".
1>ClCompile:
1>  main.cpp
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(1269): error C2100: illegal indirection
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(1152) : see reference to function template instantiation '_Rx std::_Pmf_wrap<_Pmf_t,_Rx,_Farg0,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()<std::function<_Fty>>(_Wrapper &,_V0_t) const' being compiled
1>          with
1>          [
1>              _Rx=void,
1>              _Pmf_t=void (__thiscall std::_Func_class<void,int>::* )(int) const,
1>              _Farg0=std::_Func_class<void,int>,
1>              _V0_t=int,
1>              _V1_t=std::_Nil,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil,
1>              _Fty=void (int),
1>              _Wrapper=std::function<void (int)>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(1152) : see reference to function template instantiation '_Rx std::_Pmf_wrap<_Pmf_t,_Rx,_Farg0,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()<std::function<_Fty>>(_Wrapper &,_V0_t) const' being compiled
1>          with
1>          [
1>              _Rx=void,
1>              _Pmf_t=void (__thiscall std::_Func_class<void,int>::* )(int) const,
1>              _Farg0=std::_Func_class<void,int>,
1>              _V0_t=int,
1>              _V1_t=std::_Nil,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil,
1>              _Fty=void (int),
1>              _Wrapper=std::function<void (int)>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm(24) : see reference to function template instantiation 'void std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()<std::function<_Fty>&>(std::function<_Fty>)' being compiled
1>          with
1>          [
1>              _Forced=true,
1>              _Ret=void,
1>              _Fun=std::_Pmf_wrap<void (__thiscall std::_Func_class<void,int>::* )(int) const,void,std::_Func_class<void,int>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _V0_t=std::_Ph<1> &,
1>              _V1_t=int &,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil,
1>              _Fty=void (int)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm(24) : see reference to function template instantiation 'void std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()<std::function<_Fty>&>(std::function<_Fty>)' being compiled
1>          with
1>          [
1>              _Forced=true,
1>              _Ret=void,
1>              _Fun=std::_Pmf_wrap<void (__thiscall std::_Func_class<void,int>::* )(int) const,void,std::_Func_class<void,int>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _V0_t=std::_Ph<1> &,
1>              _V1_t=int &,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil,
1>              _Fty=void (int)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm(33) : see reference to function template instantiation 'void std::_For_each<std::function<_Fty>*,_Fn1>(_InIt,_InIt,_Fn1 &)' being compiled
1>          with
1>          [
1>              _Fty=void (int),
1>              _Fn1=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall std::_Func_class<void,int>::* )(int) const,void,std::_Func_class<void,int>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,std::_Ph<1> &,int &,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _InIt=std::function<void (int)> *
1>          ]
1>          c:\users\jedwards\documents\visual studio 2012\projects\compileerror\compileerror\main.cpp(16) : see reference to function template instantiation '_Fn1 std::for_each<std::_Vector_iterator<_Myvec>,std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>>(_InIt,_InIt,_Fn1)' being compiled
1>          with
1>          [
1>              _Fn1=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall std::_Func_class<void,int>::* )(int) const,void,std::_Func_class<void,int>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,std::_Ph<1> &,int &,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _Myvec=std::_Vector_val<std::_Simple_types<std::function<void (int)>>>,
1>              _Forced=true,
1>              _Ret=void,
1>              _Fun=std::_Pmf_wrap<void (__thiscall std::_Func_class<void,int>::* )(int) const,void,std::_Func_class<void,int>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _V0_t=std::_Ph<1> &,
1>              _V1_t=int &,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil,
1>              _InIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::function<void (int)>>>>
1>          ]
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.68
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

The only thing I can come up with is bind is expecting a pointer. I tried ref() but made no difference.

Thanks, Jim


回答1:


Since VC apparently has a bug (thanks Stephan!), you could write the loop as:

for ( auto &cb : m_CBs ) cb ( m_LongPressGesture );

or:

for_each ( m_CBs.begin(), m_CBs.end(), 
             [m_LongPressGesture] ( const CB &cb ) { cb ( m_LongPressGesture ); } );



回答2:


Sounds like http://connect.microsoft.com/VisualStudio/feedback/details/763571/ , which is currently assigned to me.

Note that it is technically not allowed to take the address of most Standard Library member functions (as an implementation can have extra overloads and default arguments).

A workaround that will actually result in superior code is to use lambdas. Lambdas supersede bind() in 99% of cases, and the remaining 1% are better handled with handwritten functors.



来源:https://stackoverflow.com/questions/14837603/stdbind-on-a-vector-of-stdfunctions-compiles-in-vc10-but-not-vc11-what-did

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!