gpt4 book ai didi

c++ - 获取一个 std::tuple 元素作为 std::variant

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:01:07 31 4
gpt4 key购买 nike

给定一个变体类型:

using Variant = std::variant<bool, char, int, float, double, std::string>;

和一个包含仅限于此变体类型的元素的元组类型(重复和遗漏是可能的,但没有其他类型):

using Tuple = std::tuple<char, int, int, double, std::string>;

如何实现在运行时通过给定索引获取和设置元组元素的方法作为 Variant:

Variant Get(const Tuple & val, size_t index);
void Set(Tuple & val, size_t index, const Variant & elem_v);

我的代码中有两个实现,但我觉得可以有一个更好的实现。我的第一个实现使用 std::function,第二个实现构建了一些 Accessor 指针的数组,这些指针对移动和复制我的对象施加了限制(因为它的地址发生了变化)。我想知道是否有人知道实现这个的正确方法。

编辑 1:

下面的例子大概说明了我的意思:

Tuple t = std::make_tuple(1, 2, 3, 5.0 "abc");
Variant v = Get(t, 1);
assert(std::get<int>(v) == 2);
Set(t, 5, Variant("xyz"));
assert(std::get<5>(t) == std::string("xyz"));

最佳答案

我将继续我的主题,即为所有元编程推荐 Boost.Mp11,因为总有一个函数适合它。在这种情况下,我们想要 mp_with_index .该函数将运行时索引提升为编译时索引。

Variant Get(Tuple const& val, size_t index)
{
return mp_with_index<std::tuple_size_v<Tuple>>(
index,
[&](auto I){ return Variant(std::get<I>(val)); }
);
}

鉴于在 OP 中,Tuple 和 Variant 的索引甚至不对齐,Set 需要实际访问 Variant 而不是依赖索引。我在这里使用 is_assignable 作为约束条件,但可以根据问题进行调整(例如,它应该是 is_same)。

void Set(Tuple& val, size_t index, Variant const& elem_v)
{
mp_with_index<std::tuple_size_v<Tuple>>(
index,
[&](auto I){
std::visit([&](auto const& alt){
if constexpr (std::is_assignable_v<
std::tuple_element_t<Tuple, I>,
decltype(alt)>)
{
std::get<I>(val) = alt;
} else {
throw /* something */;
}
}, elem_v);
});
}

如果您要求 Tuple 中的每个类型在 Variant 中只出现一次,并且您只想直接从该类型赋值而不进行任何转换,这可以简化为:

void Set(Tuple& val, size_t index, Variant const& elem_v)
{
mp_with_index<std::tuple_size_v<Tuple>>(
index,
[&](auto I){
using T = std::tuple_element_t<Tuple, I>;
std::get<I>(val) = std::get<T>(elem_v);
});
}

如果变体未与该类型结合,它将抛出。

关于c++ - 获取一个 std::tuple 元素作为 std::variant,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56775116/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com