c++ - "increment"`std::variant` 替代品

标签 c++ c++20 std-variant

我想递增/递减 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)>());
}

Demo

注意:对于prevIs + 1 应该替换为Is + sizeof...(Is) - 1

关于c++ - "increment"`std::variant` 替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69674058/

相关文章:

c++ - 将变体转换为 super 集变体或子集变体

c++ - 如何以多态方式使用替代类型的 std::variant

c++ - 如何使用大值表示 C++ 中未定义的数字?

c++ - 在字符串中查找精确的子字符串

c++ - 在 Xcode 中新建一个 "Shell Tool"目标,用于 Google Test

c++ - std::views 尚未声明

C++静态空指针

c++ - 为什么 std::filter_view 没有办法立即评估它并将其转换为以 const 开头的 View ?

c++ - 我可以编写一个需要函数模板的 C++ 概念吗?必须向该函数模板提供一些枚举值作为模板参数?

c++ - std::visit无法识别类型