2016-07-20 4 views
2

클래스를 변환 할 수있는 함수 포인터 유형의 반환 형식과 인수 형식을 추출하는 템플릿을 작성할 수 있습니까? 클래스 자체 만 알고 있습니까? 예 : 다른 변환 연산자를 가지고 있지 않으며 간접 연산자를 정의하지 않습니다변환 연산자에서 함수 포인터로

struct Foo { 
    using FnPtr = int (*)(char, double); 

    operator FnPtr() const { ... } 
}; 

// Can I extract the return type (int) and argument types (char and double), 
// knowing only `Foo` as an opaque type? 

답변

6

Foo 경우에, 당신은 *a_foo 원하는 형식의 함수에 대한 참조를 줄 것이라는 사실에 의존 할 수 있습니다. 그로부터 리턴과 인수를 추출하면됩니다. 여기

func_ref_traits 추출 할 것입니다 :

template <typename Func> 
struct func_ref_traits; 

template <typename Ret, typename... Args> 
struct func_ref_traits<Ret(&)(Args...)> { 
    using ret = Ret; 
    using args = std::tuple<Args...>; 
}; 

그런 다음 conv_func_traits가 지정된 형태에서 함수 타입을 작동합니다

template <typename T> 
using conv_func_traits = func_ref_traits<decltype(*std::declval<T>())>; 

당신은과 같이이를 사용합니다 :

conv_func_traits<Foo>::args //std::tuple<char,double> 
conv_func_traits<Foo>::ret //int 
+0

나는 이것이 아마도 우리가 얻을 수있는 최선이라고 생각한다. 감사! –

3

여기 있습니다 :

#include <type_traits> 

template <typename...> struct typelist; 

template <typename> struct Extract; 

template <typename R, typename ...Args> 
struct Extract<R(*)(Args...)> 
{ 
    using Result = R; 
    using Arguments = typelist<Args...>; 
}; 



template <typename T> 
using Return_Type = typename Extract<typename T::FnPtr>::Result; 

template <typename T> 
using Arguments = typename Extract<typename T::FnPtr>::Arguments; 




struct Foo 
{ 
    using FnPtr = int (*)(char, double); 
}; 


int main() 
{ 
    static_assert(std::is_same<Return_Type<Foo>, int>::value, ":("); 
    static_assert(std::is_same<Arguments<Foo>, typelist<char, double>>::value, ":("); 
} 

필자는 인수를 나타내는 형식 목록을 사용 했으므로 더 나은 것을 원한다면 std::tuple을 사용할 수 있습니다. 또한 다른 종류의 호출 가능 항목을 처리하기 위해 Extract의 추가 전문화가 필요할 수 있습니다.

+1

그러나'Foo'는 불투명 * 타입으로 알려져 있기 때문에 안타깝게도'FnPtr' 부분을 사용할 수 없습니다. –

관련 문제