如何从向量迭代变换构造元组

时间:2018-10-17 16:47:48

标签: c++ templates variadic-templates

当前,我遇到了将json类转换为元组的问题。核心问题是从变体向量转换为特定类型的元组。

using v_t = variant<int, double, string>
using raw_t = vector<v_t> ;
template <typename... args>
optional<tuple<args...>> try_get_value(const raw_t& input);

try_get_value函数的实现应如下所示

if input.size() != sizeof...(args) return nullopt
for i in xrange(sizeof...(args)):
    if !input[i].holds_alternative<args[i]> return nullopt
return make_tuple(input[i].get<args[i]>()...)

例如,我有data = vector<v_t>({v_t(1), v_t(2)}),我想从该数据中获取tuple<int, int>,所以我叫try_get_value<int, int>(data),它应该返回make_tuple(1,1),但是如果我叫{{ 1}},它应该返回try_get_value<string,string>(data)。这些args类型是手动提供的,可能与变体向量中的类型不同。

我花了将近半天的时间来构造功能主体,但失败了。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

是的,是的。

template <class... Requested, std::size_t... RequestedIdx>
std::optional<std::tuple<Requested...>> try_get_value(
    raw_t const &input, std::index_sequence<RequestedIdx...>
) {
    // At least one of the variant contains an unexpected type, bail out
    if(!(std::holds_alternative<Requested>(input[RequestedIdx]) && ...))
        return {};

    return std::optional<std::tuple<Requested...>>(
        std::in_place, std::get<Requested>(input[RequestedIdx])...
    );
}

template <class... Requested>
std::optional<std::tuple<Requested...>> try_get_value(raw_t const &input) {
    // Incorrect vector size, bail out
    if(input.size() != sizeof...(Requested))
        return {};

    return try_get_value<Requested...>(input, std::index_sequence_for<Requested...>{});
}

See it live on Wandbox