我想递增/递减 std::variant
的替代类型,基本上像这样:
using var_t = std::variant</*...*/>;
var_t var;
var.emplace< (var.index()+1) % std::variant_size<var_t> >(); // "increment" case, wrapping for good measure
这里的问题是,虽然 emplace
期望 clang 的错误消息称为“明确指定的参数”,但 index
似乎不是 constexpr
.
明显的替代方案是这样的:
switch(var.index()){
0:
var.emplace<1>();
break;
1:
var.emplace<2>();
break;
// ...
variant_size<var_t>-1:
var.emplace<0>();
}
但这就是我个人所说的“极其丑陋”和“维护背后的巨大痛苦”(特别是因为我必须维护这些 block 的两个几乎拷贝,以用于递增和递减)。
有更好/“正确”的方法吗?
如果信息在任何方面都很重要,我将使用 libstdc++
在 clang
上针对 C++20
。
最佳答案
像往常一样,std::index_sequence
可能会有所帮助:
#include <variant>
template <typename... Ts, std::size_t... Is>
void next(std::variant<Ts...>& v, std::index_sequence<Is...>)
{
using Func = void (*)(std::variant<Ts...>&);
Func funcs[] = {
+[](std::variant<Ts...>& v){ v.template emplace<(Is + 1) % sizeof...(Is)>(); }...
};
funcs[v.index()](v);
}
template <typename... Ts>
void next(std::variant<Ts...>& v)
{
next(v, std::make_index_sequence<sizeof...(Ts)>());
}
注意:对于prev
,Is + 1
应该替换为Is + sizeof...(Is) - 1
。
关于c++ - "increment"`std::variant` 替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69674058/