2012-01-22 3 views
1

가변 매개 변수 템플릿 중 하나가 정적으로 바인딩 된 멤버 함수 포인터 인 경우 여러 가지 특수화를 가질 수 있습니까?정적으로 바인딩 된 멤버 함수 포인터가있는 가변 템플릿의 여러 특수화?

콜백 함수가 컴파일 타임 상수 인 위임을 작성하려고합니다. 따라서 옵티마이 저가 함수 포인터 경계를 지나가도록하는 데 도움이됩니다.

다음과 같은 코드를 템플릿 매개 변수로 멤버 함수 포인터를 전달합니다. 함수 포인터가 컴파일 타임에 알려진 상수이기 때문에 옵티마이 저는이 함수를 통해 작업 할 수 있습니다. 함수 포인터 경계.

저는 delegate0과 delegate1을 만들었습니다. delegate0과 delegate1은 각각 0과 1 개의 인수를 가진 멤버 함수입니다.

#include <iostream> 

template<class class_t, void (class_t::*mem_func_t)()> 
struct delegate0 
{ 
    delegate0(class_t *obj_) 
     : _obj(obj_) 
    { } 

    void operator()() 
    { 
    (_obj->*mem_func_t)(); 
    } 

private: 
    class_t *_obj; 
}; 

template<class class_t, typename arg0, void (class_t::*mem_func_t)(arg0)> 
struct delegate1 
{ 
    delegate1(class_t *obj_, arg0 a0_) 
     : _obj(obj_) 
     , _a0(a0_) 
    { } 

    void operator()() 
    { 
    (_obj->*mem_func_t)(_a0); 
    } 

private: 
    class_t *_obj; 
    arg0 _a0; 
}; 

struct app 
{ 
    void cb() 
    { 
    std::cout << "hello world\n"; 
    } 
    void cb1(int i) 
    { 
    std::cout << "hello world " << i << "\n"; 
    } 
}; 

int main() 
{ 
    app* foo = new app; 

    delegate0<app, &app::cb> f(foo); 
    f(); 

    delegate1<app, int, &app::cb1> f1(foo, 5); 
    f1(); 
} 

그러나, 나는 두 가지 방법으로 개선하고자 : 인수의 수

  1. 모든 순열을 가변 인자 위임 템플릿의 전문화 될 수 있습니다.
  2. delegate<&app::cb> (cb가 모호하지 않은 경우), class_t, mem_func_t, arg0, arg1 등을 선언하는 템플릿 인수 공제를 사용하면 app::cb의 서명에서 모두 추론됩니다.

멤버 함수 포인터가 형식이 아니라는 것을 알고 있지만 템플릿 매개 변수 (메타 프로그래밍에 사용 된 템플릿 재귀)로 특정 정수를 전달할 수있는 것처럼 특정 멤버 함수 포인터를 가질 수 있다고 생각합니다. 를 매개 변수로 사용하여 해당 함수에 대한 정적 바인딩을 허용합니다.

내가 뭘 할 수 있을까? 그렇지 않은 경우 위의 1 또는 2 중 하나가 가능합니까? 키보드를 상대로 내 머리를 쾅 쾅 대고 있었기 때문에 실제로 성공 사례를 보여주었습니다.

다음과 같은 비참한 시도가 있습니다. 그것은 내가 찾고있는 것이 분명하지 않지만 내가 향하고있는 방향을 보여주기 위해 포함하는 것이 유용하다고 생각했습니다.

template<typename...> 
struct delegate; 

template<class class_t, void (class_t::*mem_func_t)()> 
struct delegate<class_t, decltype(mem_func_t)> 
{ 
    delegate(class_t *obj_) 
     : _obj(obj_) 
    { } 

    void operator()(mem_func_t f) 
    { 
    (_obj->*f)(); 
    } 

    class_t *_obj; 
}; 

template<class class_t, typename arg0, void (class_t::*mem_func_t)(arg0)> 
struct delegate<class_t, arg0, decltype(mem_func_t)> 
{ 
    delegate(class_t *obj_, arg0 a0_) 
     : _obj(obj_) 
     , _a0(a0_) 
    { } 

    void operator()() 
    { 
    (_obj->*mem_func_t)(_a0); 
    } 

    class_t *_obj; 
    arg0 _a0; 
}; 

답변

1

어떤 종류의 복용 템플릿을 선언 :

template <typename T, T value> 
struct Delegate; 

다음 멤버 함수 객체 (그것을 할 각 CV-예선 4 회)을 위해 전문 : I로

template <typename R, typename C, typename... A, R (C::* value)(A...) const> 
struct Delegate<R(C::*)(A...) const, value> 
{ 
    // do whatever you like with R, C, A... . 
}; 

을 전에 대답 해봤자 decltype :

Delegate<decltype(&SomeClass::method), &SomeClass::method> del; 

또는 my function_traits class을 사용하여 T에서 R, C 및 A ...를 직접 추출 할 수 있으므로 전문화 할 필요가 없으므로 decltype 및 그 방법 반복은 여전히 ​​필요합니다.

+0

아, 알겠습니다 - 고마워요! –

관련 문제