我正在尝试创建一个将variadic lambda工厂方法绑定到不带参数的函数的函数。我不确定VC支持(使用VS2012与2012年11月的CTP)是不是完全存在,或者是否(更有可能)我做错了。我没有使用可变参数模板,所以任何帮助都会受到赞赏。
template <typename T, typename...Args>
std::function<T*()> MakeFactoryMethod(Args&&... args)
{
return std::bind([](Args&&... args2)
{
return new T(std::forward<Args>(args2)...);
},
std::forward<Args>(args)...);
}
...
auto test = MakeFactoryMethod<SomeClassWithSingleIntConstructor>(5);
我从编译器收到一长串错误。看起来VC标准库本身还没有使用可变参数模板。
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xrefwrap(431): error C2440: 'return' : cannot convert from 'std::_Do_call_ret<false,_Ret,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,std::tuple<int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,std::tuple<std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>::type' to 'SomeClassWithSingleIntConstructor *'
1> with
1> [
1> _Ret=void
1> ]
1> Expressions of type void cannot be converted to other types
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(239) : see reference to function template instantiation '_Ret std::_Callable_obj<std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,_Ty,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,false>::_ApplyX<_Rx>(void)' being compiled
1> with
1> [
1> _Ret=SomeClassWithSingleIntConstructor *
1> , _Ty=int
1> , _Rx=SomeClassWithSingleIntConstructor *
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(239) : see reference to function template instantiation '_Ret std::_Callable_obj<std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,_Ty,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,false>::_ApplyX<_Rx>(void)' being compiled
1> with
1> [
1> _Ret=SomeClassWithSingleIntConstructor *
1> , _Ty=int
1> , _Rx=SomeClassWithSingleIntConstructor *
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(239) : while compiling class template member function 'SomeClassWithSingleIntConstructor std::_Func_impl<_MyWrapper,_Alloc,_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Do_call(void)'
1> with
1> [
1> _Alloc=std::allocator<std::_Func_class<SomeClassWithSingleIntConstructor *,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>
1> , _Ret=SomeClassWithSingleIntConstructor *
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(514) : see reference to class template instantiation 'std::_Func_impl<_MyWrapper,_Alloc,_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Func_class<SomeClassWithSingleIntConstructor *,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>
1> , _Ret=SomeClassWithSingleIntConstructor *
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(514) : see reference to function template instantiation 'void std::_Func_class<_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=SomeClassWithSingleIntConstructor *
1> , _Ty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> , _Alloc=std::allocator<std::_Func_class<SomeClassWithSingleIntConstructor *,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>
1> , _Fty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(514) : see reference to function template instantiation 'void std::_Func_class<_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=SomeClassWithSingleIntConstructor *
1> , _Ty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> , _Alloc=std::allocator<std::_Func_class<SomeClassWithSingleIntConstructor *,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>
1> , _Fty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(514) : see reference to function template instantiation 'void std::_Func_class<_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=SomeClassWithSingleIntConstructor *
1> , _Ty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> , _Fty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> , _Alloc=std::allocator<std::_Func_class<SomeClassWithSingleIntConstructor *,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(514) : see reference to function template instantiation 'void std::_Func_class<_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=SomeClassWithSingleIntConstructor *
1> , _Ty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> , _Fty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> , _Alloc=std::allocator<std::_Func_class<SomeClassWithSingleIntConstructor *,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(675) : see reference to function template instantiation 'void std::_Func_class<_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Reset<_Ty>(_Fty &&)' being compiled
1> with
1> [
1> _Ret=SomeClassWithSingleIntConstructor *
1> , _Ty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> , _Fty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(675) : see reference to function template instantiation 'void std::_Func_class<_Ret,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Reset<_Ty>(_Fty &&)' being compiled
1> with
1> [
1> _Ret=SomeClassWithSingleIntConstructor *
1> , _Ty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> , _Fty=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> ]
1> c:\code\configurabletestserver\application.cpp(121) : see reference to function template instantiation 'std::function<SomeClassWithSingleIntConstructor *(void)>::function<std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,_Ty,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>(_Fx &&)' being compiled
1> with
1> [
1> _Ty=int
1> , _Fx=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> ]
1> c:\code\configurabletestserver\application.cpp(121) : see reference to function template instantiation 'std::function<SomeClassWithSingleIntConstructor *(void)>::function<std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,_Ty,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>>(_Fx &&)' being compiled
1> with
1> [
1> _Ty=int
1> , _Fx=std::_Bind<false,void,MakeFactoryMethod::<lambda_eabc5b7f0a2cea764c71ce16901cde81>,int,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1> ]
1> c:\code\configurabletestserver\application.cpp(139) : see reference to function template instantiation 'std::function<SomeClassWithSingleIntConstructor *(void)> MakeFactoryMethod<SomeClassWithSingleIntConstructor,int>(int &&)' being compiled
感谢。
答案 0 :(得分:3)
对我而言,看起来你正试图过度复杂化它。为什么要通过RHR捕获它们,然后将它们作为一个完美的前锋传递 - 这意味着你将捕获任何临时值 - 当你打算从中创建一个functor时?这意味着您必须将副本等传递给每个新调用以确保对象仍然存在。
template <typename T, typename...Args>
std::function<T*()> MakeFactoryMethod(Args&&... args)
{
return [=]()
{
return new T(args...);
}
}
当你必须制作副本时,只需在lambda创建中复制并完成它。
错误信息非常令人困惑,但对我来说,似乎用右手引用制作一个lambda是错误的设计,所以我对错误信息不太感兴趣。
答案 1 :(得分:0)
你的lambda返回void
应该是
template <typename T, typename...Args>
std::function<T*()> MakeFactoryMethod(Args&&... args)
{
return std::bind([](Args&&... args2) -> T*
{
return new T(std::forward<Args>(args2)...);
},
std::forward<Args>(args)...);
}