2016-06-07 4 views
4

멤버 함수에 대한 템플릿 포인터는 어떻게 가져 옵니까? 나는 다음과 같은 유형이 사전에 알려지지 않은 것을 의미 템플릿으로템플릿 템플릿이 아닌 형식의 템플릿 매개 변수를 사용하는 함수 템플릿

:

  • 템플릿 PARAM T 멤버
  • 템플릿 PARAM R는 반환 형식을입니다
  • 가변 인자 템플릿 PARAM 포인터의 클래스 Args...은 매개 변수입니다.

문제를 설명하는 데 유용한 코드 :

template <???> 
void pmf_tparam() {} 

// this works, but it's a function parameter, not a template parameter 
template <class T, typename R, typename... Args> 
void pmf_param(R (T::*pmf)(Args...)) {}  

struct A { 
    void f(int) {} 
}; 

int main() { 
    pmf_tparam<&A::f>(); // What I'm looking for 
    pmf_param(&A::f);  // This works but that's not what I'm looking for 
    return 0; 
} 

C++ 11에서 원하는 동작을 달성 할 수 있습니까?

+0

이 진정한 기능을해야합니까? 나는 잠시 C++ 게임을 빠져 있었지만, 함수를 클래스로 만들고'operator()'를 오버라이드하여 함수처럼 보이고 작동하게한다면 어떨까요? – Falmarri

답변

4

아직,이 표기법이 가능하다고 생각하지 않습니다. 이 표기법을 가능하게하는 제안은 P0127R1입니다. Oulu

template <auto P> void pmf_tparam(); 
// ... 
pmf_tparam<&S::member>(); 
pmf_tparam<&f>(); 

비 형 유형 매개 변수에 대한 auto을 추가하는 제안은 C에 투표했다 ++ 작업 용지 및 결과는 C쪽으로 이어지는 CD되기 위해 투표했다 ++ : 템플릿은 다음과 같이 선언 될 것이다 17 또한 Oulu에서.

당신이 기능에 후입니다 정말 무엇을 말하지했듯이
template <typename T, T P> void pmf_tparam(); 
// ... 
pmf_tparam<decltype(&S::member), &S::member>(); 
pmf_tparam<decltype(&f), &f>(); 
0

문제는 인수의 유형을 알지 못하고 해당 유형의 템플릿 인수를 원하고 있지 않습니다. (여전히 템플릿 매개 변수) 추가 decltype

이 작동 :

#include <iostream> 
using namespace std; 

template <typename T, T ptr> 
void foo(){ 
    ptr(); 
} 

void noop() { 
    cout << "Hello" << endl; 
} 

int main() { 
    //Here have to use decltype first 
    foo<decltype(&noop), noop>(); 

    return 0; 
} 
1

, 간단한은 다음과 같습니다 :

비 형식 매개 변수에 대한 auto 유형이 없으면, 당신은 포인터의 유형을 제공해야 것 당신이 서명을 분해하려면
struct A { 
    void bar() { 
    } 
}; 

template <typename T> 
void foo() { 
    // Here T is void (A::*)() 
} 

int main(void) { 
    foo<decltype(&A::bar)>(); 
} 

는 그러나, 나는 ... 그러나 조금 간접 때와 수,

struct A { 
    void bar() { 
     std::cout << "Call A" << std::endl;  
    } 
}; 

template <typename R, typename C, typename... Args> 
struct composer { 
    using return_type = R; 
    using class_type = C; 
    using args_seq = std::tuple<Args...>; 
    using pf = R (C::*)(Args...); 
}; 

template <typename C, typename C::pf M> 
struct foo { 
    static_assert(std::is_same<C, composer<void, A>>::value, "not fp"); 

    typename C::return_type call(typename C::class_type& inst) { 
     return (inst.*M)(); 
    } 

    template <typename... Args> 
    typename C::return_type call(typename C::class_type& inst, Args&&... args) { 
     return (inst.*M)(std::forward<Args...>(args...)); 
    } 
}; 

template <class T, typename R, typename... Args> 
constexpr auto compute(R (T::*pmf)(Args...)) { 
    return composer<R, T, Args...>{}; 
} 

int main() { 
    foo<decltype(compute(&A::bar)), &A::bar> f; 
    A a; 
    f.call(a); 
} 

위의 직접 유형을 해결할 수있는 방법이 확실하지 않다 hould 할 수있는 일

1

template <template T, T value> 
void pmf_tparam() {} 

하고있다 ... 당신이 후에 무엇을 할 다음

pmf_tparam<decltype(&A::f), &A::f>(); 
관련 문제