将std::integer_sequence作为模板参数传递给元函数
Passing std::integer_sequence as template parameter to a meta function
如何将std::integer_sequence
作为模板参数传递给元函数(即不是函数模板)?
给出以下用例(但不限于此):
我想使用整数序列从参数包中删除最后的N
类型。我想我可以从这个SO问题中使用selector
,但我未能将整数序列传递给这个元函数。
#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");
}
编译错误
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>
live on coliru
如何传递整数序列?
您需要(部分地)专门化selector
,以便从std::index_sequence
推导出索引:
#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");
}
对于这么简单的用例,您也可以将元函数写成函数模板。
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>()));
};
顺便提一下,selector
的tuple_element
实现通常效率很低,因为所需的递归模板实例化的数量是二次的。这个答案显示了一种使所需模板实例化的数量与列表中类型的数量成线性关系的方法。
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 使用指向成员的指针将成员函数作为参数传递
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 如何传递带有通过引用传递的结构参数的函数?
- 如何在 c++ 中将函数作为参数传递?
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 为什么我不能将引用作为 std::async 的函数参数传递
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 将__device__ lambda 作为参数传递给 __global__ 函数
- 是否可以在不填充自己的参数的情况下将模板函数作为参数传递?
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 将函数作为参数传递以避免重复代码
- 如何在类(C )中作为参数传递函数