如何从类型列表重建参数包
How do I rebuild parameter pack from TypeList
我有一个可变参数模板类型列表:
template <class... Types>
struct typelist {};
然后我怎样才能把它传递给一些需要参数包的外部代码,比如std::tuple
.换句话说,我需要将参数包存储为成员或类型定义在我的类型列表中,例如
...
struct typelist {
using types = Types; // Imaginary syntax
}
然而,编译器拒绝了这,说类型是未展开的。
有什么解决方法吗?
这个问题在对这个问题的评论中以另一种方式提到,但现有答案没有涵盖。
评论中要求的详细信息:
如果我编译(-std=c++17(:
template <class... T>
struct typelist {};
std::tuple<typelist<int, int>> tp{0,1};
G++ 给出了error: no matching function for call to ‘std::tuple<typelist<int, int> >::tuple(<brace-enclosed initializer list>)’
std::tuple<typelist<int, int>> tp{0,1};
如果我编译(-std=c++17(:
template <class... T>
struct typelist {
using types = T;
};
g++
给error: parameter packs not expanded with ‘...’:
using types = T;
你需要一些样板文件才能从typelist
中获得正确的tuple
专业化,因为你不能简单地按原样存储参数包。
例如,您可以通过正确使用函数声明和 using 声明来做到这一点:
#include<tuple>
#include<utility>
#include<type_traits>
template <class... T>
struct typelist {};
template<typename... T>
std::tuple<T...> foo(typelist<T...>);
template<typename L>
using tupleFromTypelist = decltype(foo(std::declval<L>()));
int main() {
using tl = typelist<int, int>;
tupleFromTypelist<tl> tp{0,1};
static_assert(std::is_same<tupleFromTypelist<tl>, std::tuple<int, int>>::value, "!");
}
或帮助程序类,如以下示例所示:
#include<tuple>
#include<utility>
#include<type_traits>
template <class... T>
struct typelist {};
template<typename>
struct helper;
template<typename... T>
struct helper<typelist<T...>> {
using type = std::tuple<T...>;
};
int main() {
using tl = typelist<int, int>;
helper<tl>::type tp{0,1};
static_assert(std::is_same<helper<tl>::type, std::tuple<int, int>>::value, "!");
}
否则,typelist
公开tuple
专用化并直接从中获取它:
#include<tuple>
#include<utility>
#include<type_traits>
template <class... T>
struct typelist {
using tuple = std::tuple<T...>;
};
int main() {
using tl = typelist<int, int>;
tl::tuple tp{0,1};
static_assert(std::is_same<tl::tuple, std::tuple<int, int>>::value, "!");
}
如果它是要使用参数包的唯一类型,则这是最简单的方法。
不能将
参数包存储在类型别名中。您需要使用模板参数推导来提取type_list
的参数以供重用。一种方法是使用虚拟函数,如下所示:
template <typename... Args>
struct type_list {};
template <typename... Args>
std::tuple<Args...> to_tuple(type_list<Args...>);
template <typename TypeList>
struct type_list_to_tuple {
using type = decltype(to_tuple(std::declval<TypeList>()));
};
template <typename TypeList>
using type_list_to_tuple_t = typename type_list_to_tuple<TypeList>::type;
int main() {
using my_type_list = type_list<int, float>;
using my_tuple = type_list_to_tuple_t<my_type_list>;
static_assert(std::is_same_v<my_tuple, std::tuple<int, float>>);
}
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- 没有名称的C++模板参数
- 如何从类型列表重建参数包