以下代码无法在VS2012中编译
class Zot
{
public:
int A() { return 123; }
};
int _tmain(int argc, _TCHAR* argv[])
{
std::function<int (Zot*)> fn = &Zot::A;
return 0;
}
但是,将作业更改为
std::function<int (Zot*)> fn = std::bind(&Zot::A, std::placeholders::_1);
是否有效。
有很多在线示例显示原始语法。在C ++ 11规范中有什么变化来禁止这种语法吗?
是否有有效的简短表格?
编辑:编译器错误(针对可重复性进行了轻微编辑)为:
1>vc\include\functional(515): error C2664: 'std::_Func_class<_Ret,_V0_t>::_Set' : cannot convert parameter 1 from '_Myimpl *' to 'std::_Func_base<_Rx,_V0_t> *'
1> with
1> [
1> _Ret=int,
1> _V0_t=Zot *
1> ]
1> and
1> [
1> _Rx=int,
1> _V0_t=Zot *
1> ]
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1> vc\include\functional(515) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Do_alloc<_Myimpl,_Fret(__thiscall Zot::* const &)(void),_Alloc>(_Fty,_Alloc)' being compiled
1> with
1> [
1> _Ret=int,
1> _V0_t=Zot *,
1> _Fret=int,
1> _Alloc=std::allocator<std::_Func_class<int,Zot *>>,
1> _Fty=int (__thiscall Zot::* const &)(void)
1> ]
1> vc\include\functional(515) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Do_alloc<_Myimpl,_Fret(__thiscall Zot::* const &)(void),_Alloc>(_Fty,_Alloc)' being compiled
1> with
1> [
1> _Ret=int,
1> _V0_t=Zot *,
1> _Fret=int,
1> _Alloc=std::allocator<std::_Func_class<int,Zot *>>,
1> _Fty=int (__thiscall Zot::* const &)(void)
1> ]
1> vc\include\functional(515) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Reset_alloc<_Fret,Zot,std::allocator<_Ty>>(_Fret (__thiscall Zot::* const )(void),_Alloc)' being compiled
1> with
1> [
1> _Ret=int,
1> _V0_t=Zot *,
1> _Fret=int,
1> _Ty=std::_Func_class<int,Zot *>,
1> _Alloc=std::allocator<std::_Func_class<int,Zot *>>
1> ]
1> vc\include\functional(515) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Reset_alloc<_Fret,Zot,std::allocator<_Ty>>(_Fret (__thiscall Zot::* const )(void),_Alloc)' being compiled
1> with
1> [
1> _Ret=int,
1> _V0_t=Zot *,
1> _Fret=int,
1> _Ty=std::_Func_class<int,Zot *>,
1> _Alloc=std::allocator<std::_Func_class<int,Zot *>>
1> ]
1> vc\include\functional(675) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Reset<int,Zot>(_Fret (__thiscall Zot::* const )(void))' being compiled
1> with
1> [
1> _Ret=int,
1> _V0_t=Zot *,
1> _Fret=int
1> ]
1> vc\include\functional(675) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Reset<int,Zot>(_Fret (__thiscall Zot::* const )(void))' being compiled
1> with
1> [
1> _Ret=int,
1> _V0_t=Zot *,
1> _Fret=int
1> ]
1> c:\..\cxx11.cpp(17) : see reference to function template instantiation 'std::function<_Fty>::function<int(__thiscall Zot::* )(void)>(_Fx &&)' being compiled
1> with
1> [
1> _Fty=int (Zot *),
1> _Fx=int (__thiscall Zot::* )(void)
1> ]
1> c:\...\cxx11.cpp(17) : see reference to function template instantiation 'std::function<_Fty>::function<int(__thiscall Zot::* )(void)>(_Fx &&)' being compiled
1> with
1> [
1> _Fty=int (Zot *),
1> _Fx=int (__thiscall Zot::* )(void)
1> ]
答案 0 :(得分:5)
以下语法有效且至少更短:
std::function<int (Zot*)> fn = std::mem_fn(&Zot::A);
答案 1 :(得分:3)
是的,它应该有效。 template<class F> function(F f);
的任何适当构造函数(例如std::function<R(ArgsTypes...)>
)的functor参数的要求之一是:
对于参数类型ArgTypes
,f应为 Callable (20.8.11.2)并返回类型
R
。
(20.8.11.2.1 functionconstruct / copy / destroy [func.wrap.func.con])
反过来,参数类型ArgTypes
的 Callable 和返回类型R
“是用伪定义的标准准概念(缺乏概念) -expression INVOKE(f, declval<ArgTypes>()..., R)
。这个伪表达式统一了常规仿函数,这些仿函数使用通常的调用语法(例如f(a, b, c)
)调用,指向具有自己怪癖的成员(例如p->*a
或(r.*a)(b, c)
)。 INVOKE 在20.8.2要求[func.require]中定义。
此外,使用std::function
的调用运算符的效果包括INVOKE(f, std::forward<ArgTypes>(args)..., R)
(20.8.11.2.4函数调用[func.wrap.func.inv]),这意味着'正确'的事情是为了指向成员的指针。
实际上还有许多其他内容也是根据标准中的 Callable / INVOKE 定义的,例如std::bind
,{{1 }},std::thread
和std::reference_wrapper
*。
*:特别是这意味着类似
std::result_of
至少出于这个原因,是有问题的。