创建变体交替值和值数组
Create variant alternating value and array of value
我想要这样的东西:
template <typename... Ts>
using make_variant_t = /* ??? */;
例如,make_variant_t<Foo, Bar>
的计算结果为
std::variant<Foo, std::vector<Foo>, Bar, std::vector<Bar>>
顺序。如果可能的话,如何实现?
给你:
namespace impl
{
template <typename R, typename ...P>
struct make_variant {};
template <typename ...R, typename P0, typename ...P>
struct make_variant<std::variant<R...>, P0, P...>
{
using type = typename make_variant<std::variant<R..., P0, std::vector<P0>>, P...>::type;
};
template <typename ...R>
struct make_variant<std::variant<R...>>
{
using type = std::variant<R...>;
};
}
template <typename ...P>
using make_variant_t = typename impl::make_variant<std::variant<>, P...>::type;
现在,make_variant_t<Foo, Bar>
应该扩展到 std::variant<Foo, std::vector<Foo>, Bar, std::vector<Bar>>
。
std::tuple
的替代解决方案:
namespace impl {
template<class> struct tuple_to_variant;
template<class... Ts>
struct tuple_to_variant<std::tuple<Ts...>> {
using type = std::variant<Ts...>;
};
}
template<class... Ts>
using make_variant_t = typename impl::tuple_to_variant<decltype(
std::tuple_cat(std::declval<std::tuple<Ts, std::vector<Ts>>>()...))>::type;
Boost.Mp11 这是一个简短的单行(一如既往):
template <typename... Ts>
using make_variant_t = mp_append<variant<Ts, vector<Ts>>...>;
make_variant_t<int, char>
首先会产生两个变体,variant<int, vector<int>>
和variant<char, vector<char>>
。在 Mp11 意义上,它们每个都是 "lists",而 mp_append
获取一堆列表并将它们连接在一起,根据需要生成 variant<int, vector<int>, char, vector<char>>
。 Demo.
我想要这样的东西:
template <typename... Ts>
using make_variant_t = /* ??? */;
例如,make_variant_t<Foo, Bar>
的计算结果为
std::variant<Foo, std::vector<Foo>, Bar, std::vector<Bar>>
顺序。如果可能的话,如何实现?
给你:
namespace impl
{
template <typename R, typename ...P>
struct make_variant {};
template <typename ...R, typename P0, typename ...P>
struct make_variant<std::variant<R...>, P0, P...>
{
using type = typename make_variant<std::variant<R..., P0, std::vector<P0>>, P...>::type;
};
template <typename ...R>
struct make_variant<std::variant<R...>>
{
using type = std::variant<R...>;
};
}
template <typename ...P>
using make_variant_t = typename impl::make_variant<std::variant<>, P...>::type;
现在,make_variant_t<Foo, Bar>
应该扩展到 std::variant<Foo, std::vector<Foo>, Bar, std::vector<Bar>>
。
std::tuple
的替代解决方案:
namespace impl {
template<class> struct tuple_to_variant;
template<class... Ts>
struct tuple_to_variant<std::tuple<Ts...>> {
using type = std::variant<Ts...>;
};
}
template<class... Ts>
using make_variant_t = typename impl::tuple_to_variant<decltype(
std::tuple_cat(std::declval<std::tuple<Ts, std::vector<Ts>>>()...))>::type;
Boost.Mp11 这是一个简短的单行(一如既往):
template <typename... Ts>
using make_variant_t = mp_append<variant<Ts, vector<Ts>>...>;
make_variant_t<int, char>
首先会产生两个变体,variant<int, vector<int>>
和variant<char, vector<char>>
。在 Mp11 意义上,它们每个都是 "lists",而 mp_append
获取一堆列表并将它们连接在一起,根据需要生成 variant<int, vector<int>, char, vector<char>>
。 Demo.