2017-03-23 3 views
1

모든 기능을 수행하고 자체 조건/준비로 실행 패턴을 구현하려고합니다. 이 작업이 유익한 작업이든 관계없이 작동하지 않습니다. 그것은 "실행"- 함수 ("메인"에서 호출)의 템플릿 과부하에 액세스 할 수없는 것 같습니다.C++ 템플릿 오버로드 호출

구체적으로 : Execute의 오버로드 된 템플릿 함수를 호출 할 수없는 이유는 무엇입니까?

이 전체 프로그램 :

#include "stdafx.h" 
#include <functional> 

class TransparentFunctionWrapper 
{ 
public: 
    virtual void Execute(std::function<void()> executeFunction) = 0; 

    template<class C> 
    C Execute(std::function<C(void)> executeFunction) // template-overload of the abstract function which will implicitly call it 
    { 
     C ret; 
     Execute(// calls the abstract function with a lambda function as parameter 
     [ret, executeFunction](void) -> C  // lambda declaraction 
     {          // 
      ret = executeFunction;    // lambda body 
     });          // 
     return ret; 
    } 
}; 

class ExampleExecutor : public TransparentFunctionWrapper 
{ 
public: 
    virtual void Execute(std::function<void()> executeFunction) 
    { 
     printf("executed before."); 
     executeFunction(); 
     printf("executed after."); 
    } 
}; 

void DoStuff() {} 
int ReturnStuff() { return -5; } 

int main() 
{ 
    ExampleExecutor executor; 

    executor.Execute(DoStuff); 
    int i = executor.Execute<int>(ReturnStuff);  // Why does this not work? ERROR: "type name is not allowed" 

    getchar(); 
    return 0; 
} 

참고 : 비주얼 스튜디오 마크

Execute<int>(ReturnStuff) // "int" is marked as Error: type name is not allowed 

컴파일 오류

"type 'int' unexpected" 

기꺼이 도와 모두에게 감사를 끈다!

+1

주의 :'ret'가 귀하의 람다에 값으로 캡처됩니다. 이것은 람다가 변경 가능하지 않은 채로 몸체에 할당하려하기 때문에 컴파일되지 않으며, 어쨌든 원하는 것을 수행하지 않을 것입니다. '[&]'로 참조로 캡처하십시오. – Quentin

+0

지적 해 주셔서 고마워. 나는이 순간에 실제로 이것을 디버깅하고 있었다. :) – Oachkatzl

답변

1

ExampleExecutor::ExecuteTransparentFunctionWrapper::Execute을 무시하지 않고 executor.Execute<int> 호출에서 숨 깁니다.

ExampleExecutor::Execute에 의해 숨겨져 있으므로 TransparentFunctionWrapper::Execute을 명시 적으로 호출해야합니다. 다음은 그 일의 가능한 방법이있다 :

int i = executor.TransparentFunctionWrapper::Execute<int>(ReturnStuff); 

live example on coliru

+0

대단히 감사합니다! "ExampleExecutor"클래스를 통해 "Execute"를 노출하는 방법을 알고 있습니까? "executor.TransparentFunctionWrapper :: Execute "으로 호출하는 것은 다소 불편합니다. : P – Oachkatzl

+0

@Oachkatzl :'TransparentFunctionWrapper :: Execute'를 호출하는'ExampleExecutor'에서 다른 이름 ** * (예 :'ExecuteBase') *로 래퍼 **를 제공 할 수 있습니다. –

+0

답변 해 주셔서 감사합니다! 이상하게도 충분히 "Execute (function )"를 "ExecuteWithReturn"으로 바꾸면 "ExampleExecutor"가 그것을 숨기지 않습니다. 기본적으로 똑같은 일을한다는 것을 분명히하기 위해 과부하를 원했기 때문에 이것은 실제로 만족스럽지 않습니다. – Oachkatzl