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

标签 c++ templates c++11 stdtuple

我有一个函数特征结构,它使用 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;
}

Working example: Ideone

如果索引i超出范围(>= arity),这会产生编译时错误。相反,我想要 args<i>::type成为void对于任何 i超出范围。

虽然我可以专攻args具体i ,例如 i == arity ,我怎么能去专攻args对于所有 i >= arity

最佳答案

使用 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

关于c++ - 如果索引超出范围,如何从 std::tuple_element 返回 void?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39406519/

相关文章:

c++ - 如何从 std::initializer_list 构建类似 std::array 的数据结构

c++ - 空白屏幕 OpenGL

C++ 模板方法 : Why Node<int> is fine, 但不是 Node<float>?

c++ - 在 c++/MFC 中读取 key 并从 .ini 文件中获取部分

android - 在android中使用opencv将检测到的人脸与现有人脸数组进行比较

visual-studio - VS 模板不复制文件,解决方案资源管理器中不显示这些文件

c++ - 奇怪地相互重复的类定义

c++ - 如何通过引用传递 vector 的静态 vector ?

c++ - boost::intrusive 中的线程安全保证

c++ - 在 map 中分配键值 - 特殊字符串(% 和 $)