std :: variant类型的向量到std :: tuple

问题描述

我正在研究std :: variant类型的向量。有没有一种方法可以将其转换为给定std :: variants持有的值的std :: tuple?

UPDATE [NAVAIR Deficiencies] 
INNER JOIN NAVAIR_Deficiencies_Temp
ON [NAVAIR Deficiencies].[Unique Deficiency Code] = NAVAIR_Deficiencies_Temp.[Unique Deficiency Code]
SET [NAVAIR Deficiencies].[Technical Data Deficiency] = [NAVAIR_Deficiencies_Temp]![Technical Data Deficiency]
WHERE (([NAVAIR Deficiencies]![Technical Data Deficiency]<>[NAVAIR_Deficiencies_Temp]![Technical Data Deficiency]));

例如,我想要一个元组,例如:

typedef std::variant<type1,type2,...> a_union;
std::vector<a_union> vec;

成员是向量中连续变体所保持的类型。

解决方法

这可能是您的解决方案,它使用可选选项,如果向量值不正确,则返回nullopt

#include <optional>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>
 
template<typename ... T,size_t ... Index>
std::optional<std::tuple<T...>> to_tuple(const std::vector<std::variant<T...>> & vec,std::index_sequence<Index...>)
{
    if (sizeof ... (T) != vec.size())
        return std::nullopt;
        
    if (not (...&& std::holds_alternative<T>(vec[Index])))
        return std::nullopt;
    return std::tuple<T...>(std::get<T>(vec[Index])...);
}

template<typename ... T>
std::optional<std::tuple<T...>> to_tuple(const std::vector<std::variant<T...>>& vec)
{
    return to_tuple(vec,std::index_sequence_for<T...>{});
}
,

这些注释准确地指出这可能是一个XY问题-元组需要有关变体向量所不包含的每个索引处的数据类型的编译时信息。

但是,如果您愿意在呼叫站点提供该信息,则可以很容易地使用参数包扩展将类型列表映射到对std::get<>的调用字符串

您可以通过提供变体中的类型列表,方法是假设变体中的类型顺序是每个索引处所需的变体类型,就像jo-art的答案一样。这是一种方法,只需提供一个您希望向量包含的元组的类型列表,以防它们不同:

template<typename... Ts,typename Container,std::size_t... Is>
auto vector_to_tuple_impl(Container&& items,std::index_sequence<Is...>)
{
    return std::make_tuple(std::get<Ts>(items[Is])...);
}

template <typename... Ts,typename Container>
std::tuple<Ts...> vector_to_tuple(Container&& items)
{
    return vector_to_tuple_impl<Ts...>(items,std::index_sequence_for<Ts...>{});
}

(这里没有错误处理,如果类型错误,它将抛出std::bad_variant_access,如果提取的元素多于存在的元素,则抛出不确定的行为)

这是相同的基本策略:使用std::index_sequence_for将参数包转换为包含容器索引(0、1、2等)的可扩展参数包。整数序列包和类型包一起展开以获取每个索引处的项目,然后调用std::get来提取值。

用法:

    using SimpleVariant = std::variant<std::string_view,int>;
    std::vector<SimpleVariant> some_list { "hello",42,"goodbye" };
    auto as_tuple = vector_to_tuple<std::string_view,int,std::string_view>(some_list);

概念验证: https://godbolt.org/z/cGEW5s

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...