2013-03-31 4 views
1

가변 인수 람다 팩토리 메소드를 매개 변수를 사용하지 않는 함수에 바인드하는 함수를 작성하려고합니다. 나는 VC (11 월 2012 CTP와 함께 VS2012 사용) 지원이 완전히 존재하지 않거나 잘못 (틀림없이) 할 지 확실하지 않습니다. 난 variadic 템플릿으로 많은 일을하지 않았으므로 어떤 도움을 주시면 감사하겠습니다.가변성 람다 바인딩 문제

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

당신은 [SSCCE] (http://sscce.org) –

+0

을 제공해야합니다. 문제는 lambda가 무효라고 생각하지만 포인터 – kassak

+0

을 반환합니다. 일치하는 구현이 있다고해도 람다가 필요합니다 Args &&가 아닌'Args & ... '를 받아 들일 수 있습니다. 'std :: bind' 인수의 바운드 인수는 항상 lvalues로서 전달됩니다. [예] (http://coliru.stacked-crooked.com/view?id=c0791276414f1ce68d1878e55eb9f285-50d9cfc8a1d350e7409e81e87c2653ba). –

답변

3

당신이 그것을 복잡하게하려는 것 같습니다해야 반환합니다. 왜 RHR에 의해 그것을 포착하고 완벽한 전진으로서 건네줍니다. 즉 일시적인 것으로 일시적인 것을 포착한다는 것을 의미합니다. 즉, 객체가 여전히 존재하는지 확인하기 위해 사본을 새로 호출 할 때마다 전달해야합니다.

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

복사본을 만들려면 람다 생성시 복사본을 만들어서 완료해야합니다.

오류 메시지는 매우 혼란 스럽지만 나에게 람다를 옳은 참조로 만드는 것은 의도적으로 잘못되어있는 것처럼 보였으므로 오류 메시지에 너무 열중하지 않습니다.

+0

좋은 지적입니다. 이 사용 사례의 경우 많은 불필요한 작업을 수행하고있었습니다. 나는이 해결책을 사용했다. 감사. – TractorPulledPork

0

귀하의 람다 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)...); 
} 
+0

아니요, 단일 명령문을 사용하면 람다가 반환 유형을 추론 할 수 있습니다. – Xeo

+0

@Xeo'_Ret std :: _ Callable_obj 'analogue가 도움이 될 것입니다. – kassak