c++ 展开模板类型

xmjla07d  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(146)

有没有办法把每种类型的std::tuple转换成特定的子类型呢?

struct Foo1
{
    struct A{};
    struct B{};
};

struct Foo2
{
    struct A{};
    struct B{};
};

using myTypes = std::tuple<Foo1, Foo2>;

有没有办法把myTypes转换成下面的类型?

std::tuple<Foo1::A, Foo1::B, Foo2::A, Foo2::B>;

类型的顺序并不重要,但最好像上面这样。

hk8txs48

hk8txs481#

如果A/B名称是固定的,您可以

template <typename... Ts>
using AB_Types = std::tuple<typename Ts::A..., typename Ts::B...>;

所以AB_Types<Foo1, Foo2>就是std::tuple<Foo1::A, Foo2::A, Foo1::B, Foo2::B>
具有预期的次序也是可能的:

template <typename... Ts>
using AB_Types_ordered =
    decltype(std::tuple_cat(std::tuple<typename Ts::A, typename Ts::B>{}...));

如果源是元组,只需添加额外的层

template <typename>
struct AB_impl;

template <typename... Ts>
struct AB_impl<std::tuple<Ts...>>
{
    using type = AB_Types<Ts...>; // AB_Types_ordered<Ts...>
};

template <typename T>
using AB_Types_from_tuple = typename AB_impl<T>::type;
nmpmafwu

nmpmafwu2#

基于Boost.Mp11库的替代解决方案:

template<class T>
using add_AB = std::tuple<typename T::A, typename T::B>;

template <typename Tuple>
using AB_Types_from_tuple = 
    boost::mp11::mp_flatten<boost::mp11::mp_transform<add_AB, Tuple>>;

static_assert(std::is_same_v<
    AB_Types_from_tuple<myTypes>,
    std::tuple<Foo1::A, Foo1::B, Foo2::A, Foo2::B>
>);

相关问题