c++ - 无法绑定(bind)可变 lambda

标签 c++ visual-c++ c++11 variadic-templates

我正在尝试创建一个函数,它将可变参数 lambda 工厂方法绑定(bind)到一个不带参数的函数。我不确定 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

谢谢。

最佳答案

在我看来,您似乎正试图将其复杂化。为什么要用 RHR 捕获它们然后将它们作为完美的前向传递 - 这意味着你将捕获任何临时值作为临时值 - 当你要用它制作仿函数时?这意味着您必须将拷贝或类似内容传递到每个新调用中,以确保对象仍然存在。

template <typename T, typename...Args>
std::function<T*()> MakeFactoryMethod(Args&&... args)
{
    return [=]()
        {
            return new T(args...);
        }
}

当您确实需要制作拷贝时,只需在 lambda 创建中制作一个拷贝即可完成。

错误消息非常令人困惑,但对我来说,从右手引用中创建 lambda 似乎是设计错误的,所以我对错误消息并不太在意。

关于c++ - 无法绑定(bind)可变 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15730744/

相关文章:

c++ - 在 buildbot 上构建后,Qt 应用程序变为 Windows 旧样式

c++ - 解析在 XML 中的 C/C++ 头文件中定义的嵌套结构/union

c++ - rand() 生成相同的数字

c++ - C++11 中有新的函数类型表达式格式吗?

C++:试图在类中封装 std::enable_if

c++ - 指针和 {l,r} 值引用的通用名称?

c++ - Qt Widget 中的默认初始化列表

c++ - 为什么 gdb 总是给出 "Program exited with code 01"?

c# - 装配加载失败

c++ - getline() 没有填充整个字符串数组