【问题标题】:How to create std::tuple of subtypes from std::tuple of given typelist如何从给定类型列表的 std::tuple 创建子类型的 std::tuple
【发布时间】:2021-10-16 12:47:30
【问题描述】:

我有一个 std::tuple 形式的类型列表

struct A { struct data_type {}; };
struct B { struct data_type {}; };
struct C { struct data_type {}; };
struct D { struct data_type {}; };
//etc

using my_typelist = std::tuple<A, B, C, D>;

我定义了元组的变量,包含内部类型。像这样的

std::tuple<A::data_type, B::data_type, C::data_type, D::data_type> data;

但简单的解决方案不起作用(https://ideone.com/c8a2FE):

#include <tuple>
#include <iostream>

struct A { using data_type = int; };
struct B { using data_type = char; };

// error: template argument for template type parameter must be a type
template < typename... Ts >
using cvt_2_data = std::tuple< Ts::data... >; 

void main()
{
    using my_typelist = std::tuple<A, B>;
    cvt_2_data<my_typelist> data;
    std::cout 
        << std::get<A::data_type>(data) << " "
        << std::get<B::data_type>(data) << std::endl;
}

我也试过这个,更复杂的方法,但没有这样的运气

std::tuple< (Ts::data)... >;
std::tuple< decltype(Ts)::data... >;

顺便说一下,我需要 C++17 的解决方案

【问题讨论】:

  • typename Ts::data...
  • 是的,“typename Ts::data...”很重要,但还不够

标签: c++ templates c++17 variadic typelist


【解决方案1】:

您似乎想指定std::tuple&lt;A, B&gt; 作为模板参数,并获取类型std::tuple&lt;A::data_type, B::data_type&gt;。您可以使用帮助模板和专业化来做到这一点。例如

template < typename... Ts >
struct cvt_2_data_struct; 
template < typename... Ts >
struct cvt_2_data_struct<std::tuple<Ts...>> {
    using type = std::tuple< typename Ts::data_type... >; 
};

template < typename... Ts >
using cvt_2_data = typename cvt_2_data_struct<Ts...>::type;

LIVE

顺便说一句:注意typenametypename Ts::data_type...typename cvt_2_data_struct&lt;Ts...&gt;::type 中的用法,它用于告诉依赖限定名称是类型。见Where and why do I have to put the “template” and “typename” keywords?

【讨论】:

  • 非常感谢。我在哪里可以了解为什么您的方法有效而我的方法无效?我的意思是除了 c++ 标准。
  • @RedApe 你的问题很特别,在这里提问是个好主意。您可以在 cppreference.com 上浏览文档。如果你想看书,请参考The Definitive C++ Book Guide and List
【解决方案2】:

尝试使用类/结构模板的部分特化:

template < typename T >
struct cvt_2_data_struct {};
template < typename... Ts >
struct cvt_2_data_struct<std::tuple< Ts... >> {
    using type = std::tuple< typename Ts::data_type... >;
};

template < typename T >
using cvt_2_data = typename cvt_2_data_struct<T>::type;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-15
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多