首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从TypeList重新生成参数包

如何从TypeList重新生成参数包
EN

Stack Overflow用户
提问于 2017-04-01 11:00:52
回答 2查看 1.6K关注 0票数 9

我有一个各种各样的模板打字员:

代码语言:javascript
复制
template <class... Types>
struct typelist {};

然后,我如何将它传递给期望参数包的外部代码,std::tuple说。换句话说,我需要将参数包存储为我的打字员中的一个成员或类型--如

代码语言:javascript
复制
...
struct typelist {
    using types = Types; // Imaginary syntax
}

但是编译器拒绝这一点,说类型是未展开的。

有什么解决办法吗?

这个问题在https://stackoverflow.com/questions/40097153/how-to-revert-a-typelist-back-to-its-original-parameter-pack中是以另一种方式提到的,但是现有的答案并没有涉及到这个问题。

评论中所要求的详细情况:

如果我编译(-std=c++17):

代码语言:javascript
复制
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):

代码语言:javascript
复制
template <class... T>
struct typelist {
    using types = T;
};

g++给出error: parameter packs not expanded with ‘...’: using types = T;

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-01 11:47:20

您需要一些样板才能从tuple中获得正确的typelist专门化,因为您不能简单地存储参数包。

例如,您可以通过正确地使用函数声明和使用声明来做到这一点:

代码语言:javascript
复制
#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, "!");
}

或者类似于下面示例中的帮助类:

代码语言:javascript
复制
#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专门化并直接从它获得它:

代码语言:javascript
复制
#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, "!");
}

如果它是您想要使用参数包的唯一类型,这是最简单的方法。

票数 10
EN

Stack Overflow用户

发布于 2017-04-01 11:47:00

不能将参数包存储在类型别名中。您需要使用模板参数演绎来提取type_list的参数以供重用。一种方法是使用这样的虚拟函数:

代码语言:javascript
复制
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>>);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43155987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档