c++ 连接std::variant< a,B,c>和std::variant< x,y,z>类型

k4emjkb1  于 2023-05-20  发布在  其他
关注(0)|答案(2)|浏览(111)

有没有一种方法可以从两个现有的变量类型中声明第三个变量,其中包含两个变量类型的并集?

#include <variant>

using Var1 = std::variant<int, bool>;
using Var2 = std::variant<float, double>;

// both lines should yield the same
using MergedVariant = VariantUnion<Var1, Var2>; // <-- how to do this?
using MergedVariant = std::variant<int, bool, float, double>; // expected
ryhaxcpt

ryhaxcpt1#

您可以使用这样的帮助器类型进行演绎:

#include <variant>

template <class ...Args>
struct VariantUnionHelper;

template <class ...Args1, class ...Args2>
struct VariantUnionHelper<std::variant<Args1...>, std::variant<Args2...>> {
    using type = std::variant<Args1..., Args2...>;
};

与方便的类型别名一起使用

template <class Variant1, class Variant2>
using VariantUnion = typename VariantUnionHelper<Variant1, Variant2>::type;

这允许以下使用情形

using Var1 = std::variant<int, long, short>;
using Var2 = std::variant<bool, char, double>;
VariantUnion<Var1, Var2> joined;

并通过以下编译时检查。

#include <type_traits>

static_assert(std::is_same_v<VariantUnion<Var1, Var2>,
     std::variant<int, long, short, bool, char, double>>);
zphenhs4

zphenhs42#

lubgr形式的解决方案很好,但有一些缺点。它只接受两个参数,只适用于std::variant,不考虑样式中的命名:struct Xusing X_t类似于STL。

template <class... Args>
struct template_concat;

template <template <class...> class T, class... Args1, class... Args2, typename... Remaining>
struct template_concat<T<Args1...>, T<Args2...>, Remaining...> {
    using type = typename template_concat<T<Args1..., Args2...>, Remaining...>::type;
};

template <template <class...> class T, class... Args1>
struct template_concat<T<Args1...>> {
    using type = T<Args1...>;
};

template <class... Args>
using template_concat_t = typename template_concat<Args...>::type;

static_assert(std::is_same_v<
    template_concat_t<
        std::variant<int, long, short>,
        std::variant<bool, char, double>>,
    std::variant<int, long, short, bool, char, double>>);

https://godbolt.org/z/T37KE81nf
我不喜欢template_concat的名字,但我不能拿出更好的版本。

相关问题