2016-07-02 2 views
1

NULL 값을 가질 수있는 여러 함수 포인터를 래핑해야합니다. 포인터가 NULL이 아닌 경우 함수 포인터가 NULL인지 원래 함수를 호출하고 포인터가 NULL이면 기본 값을 반환하는 일반 클래스 템플릿을 만들려고합니다. 이런 식으로 뭔가가 :NULL 검사를 사용하는 일반 C++ 함수 포인터 래퍼를 만들 수 있습니까?

볼 수 있듯이
//Function typedefs 
typedef void(*foo)(); 
typedef int(*bar)(int u, char *); 

//Function pointers 
foo gfFoo; 
bar gfBar; 

//Wrapper class 
template<typename T, typename... Args> 
class WrapFuncObj { 
    T* f; 
public: 
    WrapFuncObj(T* t) { 
     f = t; 
    } 
    typename std::result_of<T(Args...)>::type operator()(Args&&... args) { 
     if(f != nullptr){ 
      return (*f)(std::forward<Args>(args)...); 
     } 
     else 
     { 
      return 0; //RETURN something for non-void types 
     } 
    } 
}; 

template<typename T, typename... Args> 
class WrapFuncObjVoid { 
    T* f; 
public: 
    WrapFuncObjVoid(T* t) { 
     f = t; 
    } 
    typename std::result_of<T(Args...)>::type operator()(Args&&... args) { 
     if(f != nullptr){ 
      (*f)(std::forward<Args>(args)...); 
     } 
     else 
     { 
      //DO Nothing for void 
     } 
    } 
}; 

//Usage: 
WrapFuncObjVoid<foo> WrapFoo(&gfFoo); 
WrapFoo(); 
WrapFuncObj<bar, int, char*> WrapBar(&gfBar); 
WrapBar(0, "test"); 

, 함수 포인터가 NULL 인 경우 때문에 널 (null)의 경우, 아무것도 반환해야 비 무효 및 무효 유형에 대해 별도의 템플릿이있을 필요가있다. 이 문제를 피하고 둘 다 사용할 수있는 단일 템플릿을 만드는 방법은 무엇입니까?

+0

어딘가에 'void'리턴 유형을 특화시키는 것을 피할 방법이 없습니다. –

+0

@SamVarshavchik : 예, 있습니다. [C++에서는 void를 반환 할 수 있습니다 (http://stackoverflow.com/questions/3383090/is-returning-void-valid-code). – Cornstalks

+0

그들이 null을 생성자에 전달하면 포인터를 기본 함수로 설정하지 않는 이유는 무엇입니까? –

답변

3

return T(); (원하는 반환 유형은 T이라고 가정 할 수 있음). 이것은 void 유형에서 작동합니다. 기본이 아닌 생성자가있는 유형에서는 작동하지 않습니다.

#include <iostream> 
#include <utility> 

void foo() { 
    std::cout << "void foo()\n"; 
} 

int bar(int u, char* c_str) { 
    std::cout << "int bar(" << u << ", \"" << c_str << "\")\n"; 
    return u; 
} 

template<typename T> 
class WrapFuncObj; 

template<typename T, typename... Args> 
class WrapFuncObj<T(Args...)> { 
    T (*f)(Args...); 
public: 
    WrapFuncObj(T (*t)(Args...)) { 
     f = t; 
    } 

    T operator()(Args&&... args) { 
     if(f != nullptr) { 
      return (*f)(std::forward<Args>(args)...); 
     } else { 
      return T(); 
     } 
    } 
}; 

int main() { 
    WrapFuncObj<void()> wrap_foo(&foo); 
    wrap_foo(); 

    WrapFuncObj<int(int, char*)> wrap_bar(&bar); 
    wrap_bar(0, "test"); 

    WrapFuncObj<void()> wrap_null(nullptr); 
    wrap_null(); // prints nothing. 
} 

Live demo.

std::function을 제안해야 할 의무가 있습니다. null 기능을 호출하고 사용자가 실제로하고 싶어하지 않을 수도있는 기본 유형을 반환하는 것을 제외하고는 재발견하려고합니다.

+0

고마워요! 그것은 내가 찾고 있던 바로 그 것이다. std :: function에 대해 읽었습니다. 그러나 함수 포인터가 선택적 함수이므로 함수 포인터가 null 일 수 있으며 기본값을 반환하는 것이 좋습니다. 다시 당신의 도움에 많은 감사드립니다! –