2016-09-09 4 views
5

나는 함수의 인수의 유형을 제공하는 기능 특성 구조체가 std::tuple_element를 사용하여이 : 인덱스 i 범위 (>= arity)를 벗어나면인덱스가 범위를 벗어난 경우 std :: tuple_element에서 void를 반환하는 방법은 무엇입니까?

#include <iostream> 
#include <tuple> 
#include <typeinfo> 

template <typename T> 
struct function_traits; 

template <typename T_Ret, typename ...T_Args> 
struct function_traits<T_Ret(T_Args...)> { 
    // Number of arguments. 
    enum { arity = sizeof...(T_Args) }; 
    // Argument types. 
    template <size_t i> 
    struct args { 
     using type 
      = typename std::tuple_element<i, std::tuple<T_Args...>>::type; 
    }; 
}; 

int main() { 
    using Arg0 = function_traits<int(float)>::args<0>::type; 
    //using Arg1 = function_traits<int(float)>::args<1>::type; // Error, should be void. 

    std::cout << typeid(Arg0).name() << std::endl; 
    //std::cout << typeid(Arg1).name() << std::endl; 
} 

Working example: Ideone

,이 컴파일 타임 오류를 제공합니다 . 대신 i 범위를 벗어난 경우 args<i>::typevoid으로 변경하겠습니다.

내가 i == arity와 같은 특정 i에 대한 args를 전문으로 할 수 있지만, 어떻게 나는 모든 i >= arity에 대한 args를 전문에 대해 갈 수 있을까? std::conditional 및 추가 간접으로

+0

당신은 우리의 코드를 확장 할 수 있습니다. 그래서 우리는 이것을 컴파일 할 수 있습니까? 간단한 사용 사례와 비슷합니다. – Hayt

+0

@Hayt 완료 : http://ideone.com/qM9Jxp – zennehoy

답변

4

는 :

struct void_type { using type = void; }; 


template <typename T_Ret, typename ...T_Args> 
struct function_traits<T_Ret(T_Args...)> { 
    // Number of arguments. 
    enum { arity = sizeof...(T_Args) }; 

    // Argument types. 
    template <size_t i> 
    struct args { 
     using type 
      = typename std::conditional<(i < sizeof...(T_Args)), 
             std::tuple_element<i, std::tuple<T_Args...>>, 
             void_type>::type::type; 
    }; 
}; 

Demo