Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将std::integer_序列作为模板参数传递给元函数_C++_Templates_C++14 - Fatal编程技术网

C++ 将std::integer_序列作为模板参数传递给元函数

C++ 将std::integer_序列作为模板参数传递给元函数,c++,templates,c++14,C++,Templates,C++14,如何将std::integer\u序列作为模板参数传递给元函数(即,不是函数模板) 例如,给出以下用例(但不限于此): 我想使用整数序列从参数包中删除最后的N类型。我想我可以使用selectorfrom,但是我无法将整数序列传递给这个元函数 #include <tuple> #include <utility> template <typename T, std::size_t... Is> struct selector { using type

如何将
std::integer\u序列作为模板参数传递给元函数(即,不是函数模板)

例如,给出以下用例(但不限于此):

我想使用整数序列从参数包中删除最后的
N
类型。我想我可以使用
selector
from,但是我无法将整数序列传递给这个元函数

#include <tuple>
#include <utility>

template <typename T, std::size_t... Is>
struct selector
{
    using type = std::tuple<typename std::tuple_element<Is, T>::type...>;
};

template <std::size_t N, typename... Ts>
struct remove_last_n
{
    using Indices = std::make_index_sequence<sizeof...(Ts)-N>;  
    using type = typename selector<std::tuple<Ts...>, Indices>::type; // fails
};

int main()
{
    using X = remove_last_n<2, int, char, bool, int>::type;
    static_assert(std::is_same<X, std::tuple<int, char>>::value, "types do not match");
}
#包括
#包括
模板
结构选择器
{
使用type=std::tuple;
};
模板
结构删除\u最后\u n
{
使用index=std::生成索引序列;
使用type=typename选择器::type;//失败
};
int main()
{
使用X=remove\u last\u n::type;
静态断言(std::is_same::value,“类型不匹配”);
}
编译器错误

main.cpp:15:55: error: template argument for non-type template parameter must be an expression

using type = typename selector<std::tuple<Ts...>, Indices>::type; // fails

                                                  ^~~~~~~

main.cpp:5:38: note: template parameter is declared here

template <typename T, std::size_t... Is>
main.cpp:15:55:错误:非类型模板参数的模板参数必须是表达式
使用type=typename选择器::type;//失败
^~~~~~~
main.cpp:5:38:注意:这里声明了模板参数
模板

如何传递整数序列?

您需要(部分)专门化
选择器
,以便从
std::index_序列
推导索引:

#include <tuple>
#include <utility>
#include <type_traits>

template <typename T, typename U>
struct selector;

template <typename T, std::size_t... Is>
struct selector<T, std::index_sequence<Is...>>
{
    using type = std::tuple<typename std::tuple_element<Is, T>::type...>;
};

template <std::size_t N, typename... Ts>
struct remove_last_n
{
    using Indices = std::make_index_sequence<sizeof...(Ts)-N>;  
    using type = typename selector<std::tuple<Ts...>, Indices>::type;
};

int main()
{
    using X = remove_last_n<2, int, char, bool, int>::type;
    static_assert(std::is_same<X, std::tuple<int, char>>::value, "types do not match");
}
#包括
#包括
#包括
模板
结构选择器;
模板
结构选择器
{
使用type=std::tuple;
};
模板
结构删除\u最后\u n
{
使用index=std::生成索引序列;
使用type=typename选择器::type;
};
int main()
{
使用X=remove\u last\u n::type;
静态断言(std::is_same::value,“类型不匹配”);
}

对于如此简单的用例,您也可以将元函数作为函数模板编写

template<class...> class wrapper{};

template <typename T, std::size_t... Is>
std::tuple<typename std::tuple_element<Is, T>::type...>
    selector_impl(wrapper<T, std::index_sequence<Is...>>);    

template <std::size_t N, typename... Ts>
struct remove_last_n
{
    using Indices = std::make_index_sequence<sizeof...(Ts)-N>;  
    using type = decltype(selector_impl(wrapper<std::tuple<Ts...>, Indices>()));
};
模板类包装器{};
模板
std::tuple
选择器_impl(包装器);
模板
结构删除\u最后\u n
{
使用index=std::生成索引序列;
使用type=decltype(选择器_impl(wrapper());
};
顺便提一下,
selector
tuple\u元素
实现通常效率很低,因为所需的递归模板实例化的数量是二次的。显示了使列表中所需的模板实例化数量与类型数量成线性关系的一种方法