如果索引超出范围,如何从std::tuple_element返回void?

6
我有一个函数特征结构体,它使用std::tuple_element提供了函数参数的类型:
#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;
}

工作示例:Ideone

如果索引 i 超出范围(>= arity),将会导致编译时错误。相反,我想让任何超出范围的 iargs<i>::type 变为 void

虽然我可以为特定的 i,例如 i == arity 进行专门化处理,但我应该如何为所有 i >= arity 进行专门化处理?


你能为我们扩展代码,这样我们就可以编译它吗?例如使用一个简单的用例等。 - Hayt
@Hayt 完成了:http://ideone.com/qM9Jxp - zennehoy
1个回答

5

使用 std::conditional 和额外的间接:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接