2012-04-23 4 views
1

SFINAE 및 기본 템플릿 인수를 사용하는이 코드가 있습니다. 예상대로 지난 2 개 주석 라인을 제외하고 작동합니다함수 템플릿 오버로드 주소 가져 오기

#include <tuple> 
#include <iostream> 
using namespace std; 

template<typename T> void push(T val){ 
    cout<<val<<endl; 
} 

template<typename T> T to(){ 
    T dummy; 
    cin>>dummy; 
    return dummy; 
} 

template<typename T, T> class function_proxy{ 
    static_assert(sizeof(T)!=sizeof(T), "Error: function_proxy works with functions (duh)"); 
}; 

template<typename Return, typename... Args, Return(*func)(Args...)> class function_proxy<Return(*)(Args...), func>{ 
    static Return call(Args... args){ 
     return func(args...); 
    } 
    template<typename... retrieved> static Return call(retrieved... read){ 
     return call(read..., to<typename tuple_element<sizeof...(read), tuple<Args...> >::type >()); 
    } 
public: 
    template<typename Ret=Return, typename enable_if<!is_void<Ret>::value, int>::type=0> 
    static int wrapper(){ 
     push(call()); 
     return 1; 
    } 

    template<typename Ret=Return, typename enable_if<is_void<Ret>::value, int>::type=0> 
    static int wrapper(){ 
     call(); 
     return 0; 
    } 
}; 

int f(int arg){ return arg*3; } 
void g(){ cout<<"g does nothing"<<endl; } 

int main(){ 
    //SFINAE works nicely 
    function_proxy<decltype(&f), &f>::wrapper(); 
    function_proxy<decltype(&g), &g>::wrapper(); 
    //Here it doesn't, even though there should be no ambiguity: 
    //function_proxy<decltype(&f), &f>::wrapper; 
    //function_proxy<decltype(&g), &g>::wrapper; 
} 

당신은 내가 템플릿 함수를 호출 할 때, SFINAE 그 일을 볼 수 있습니다. 그러나 잘못된 형식이 아닌 유일한 기능의 주소를 취하려고 할 때 g ++은 오버로드 된 함수의 주소를 확인할 수 없다는 불만을 표시합니다.

이러한 오버로드 된 함수의 첫 번째 템플릿 매개 변수를 명시 적으로 말하지 않고도이 문제를 해결할 수있는 방법이 있습니까? 이론 상으로는 중복 적입니다. 또한,이 도우미 클래스를 사용하는 코드는 매우 일반적이고 여기에서 반환 유형은 fg이므로 가져 오기가 그리 간단하지 않을 수 있습니다.

답변

0

SFINAE는 과부하 해결 중에 만 적용되며 함수 호출이없는 경우 과부하 해결 방법이 없습니다.

+0

나는 본다. 요점은 내가 확실히 그것이 안전하다고 생각하고 당신이 이런 식으로 주소를 가질 때 SFINAE를 갖는 것이 합리적이라고 생각합니다. 이것이 미래의 표준에서 일어날 수있는 기회가 있습니까? –

+0

@LorenzoPistone - 누가 압니다. SFINAE의 이러한 내성적인 사용은 진단, 쉬운 사용 (템플릿 및 함수 호출) 및 컴파일러 구현의 용이성 (형식 공제, 과부하 해결)에 중점을 둔 원래 제안의 일부가 아니 었습니다. 다른 언어들도 표준 인트로 스펙 션 기능을 가지고 있으며 아마도 C++이 언젠가 그 소송을 따를 것입니다. 또는 미래가 우리에게 더 많은 SFINAE를 가져다 줄 수 있습니다. –