将元组转换为变体

时间:2017-12-01 18:54:11

标签: c++ metaprogramming c++17

我有以下类型

using MyTuple=std::tuple<std::vector<char>,std::vector<double>,std::vector<int>>;

如何编写将MyTuple转换为以下类型的元函数?

std::variant<std::monostate,char,double,int> 

2 个答案:

答案 0 :(得分:2)

#include <vector>
#include <tuple>
#include <variant>

template <typename Tuple>
struct get_variant;

template <typename... Ts>
struct get_variant<std::tuple<Ts...>>
{
    using type = std::variant<std::monostate, typename Ts::value_type ...>;
};


using MyTuple = std::tuple<std::vector<char>,std::vector<double>,std::vector<int>>;
using MyVariant = typename get_variant<MyTuple>::type;

using Expected = std::variant<std::monostate,char,double,int>;
static_assert(std::is_same_v<Expected, MyVariant>);

live example

答案 1 :(得分:2)

你可以使用一个函数声明(不需要定义),一些模板机器和decltype来做到这一点。
例如,这是一个不会停留在矢量确切数量上的解决方案(但如果需要,可以轻松强制执行):

template<typename... T>
std::variant<std::monostate, T...>
f(std::tuple<std::vector<T>...>);

template<typename T>
using to_variant = decltype(f(std::declval<T>()));

这是一个最小的工作示例:

#include<tuple>
#include<variant>
#include<vector>
#include<utility>
#include<type_traits>

template<typename... T>
std::variant<std::monostate, T...>
f(std::tuple<std::vector<T>...>);

template<typename T>
using to_variant = decltype(f(std::declval<T>()));

using MyTuple = std::tuple<std::vector<char>,std::vector<double>,std::vector<int>>;

int main() {
    static_assert(std::is_same_v<
        to_variant<MyTuple>,
        std::variant<std::monostate,char,double,int>
    >);
}

wandbox上查看并运行。