c++ - 遍历 std::variant 的映射

标签 c++ c++17 variant

我正在试验 C++17 的 std::variant在 map 中存储多种类型的数据。这里的用例是有一个通用类型的 Controller 映射(但受 std::variant 约束),我可以迭代并调用其方法。 在下面的例子中,

#include <iostream>
#include <map>
#include <variant>

class ControlA {
public:
    void specificToA() { std::cout << "A" << std::endl; }
};

class ControlB {
public:
    void specificToB() { std::cout << "B" << std::endl; }
};

template<typename T>
class ControlItem{
    T* control;

public:
    ControlItem() = default;
    ~ControlItem() = default;

    void doStuff() {
        if constexpr (std::is_same_v<T, ControlA>) {
            control->specificToA();
        }
        if constexpr (std::is_same_v<T, ControlB>) {
            control->specificToB();
        }
    }
};

class MyClass {
public:
    void cycleThroughMap();
    std::map<std::string, std::variant<ControlItem<ControlA>, ControlItem<ControlB>>> controlMap;
};

启发式方法是获取每个声明类型的映射值,如:

void MyClass::cycleThroughMap() {
    for (auto controlItem : controlMap) {
        if (auto control = std::get_if<ControlItem<ControlA>>(&controlItem.second)) {
            control->doStuff();
         } else if (auto control = std::get_if<ControlItem<ControlB>>(&controlItem.second)) {
            control->doStuff();
         } else
            std::cout << "Unknown type!" << std::endl;
    }
}

这有效,但感觉它不应该存在。
std::variant 可以用于此吗?从一开始就是个坏主意,我应该使用继承吗?

最佳答案

Can std::variant be used for this?

是的。您的代码已准备好有效使用变体。变体包含具有相同隐式接口(interface)的类型。这是使用 std::visit 的绝好机会使用通用 lambda。

void MyClass::cycleThroughMap() {
    for (auto& [ key, control ] : controlMap) {
        std::visit([](auto&& c) {
          c.doStuff();
        }, control);
    }
}

我还冒昧地用结构化绑定(bind)替换了对访问。为了更加简单。

关于c++ - 遍历 std::variant 的映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50210104/

相关文章:

c++ - 迭代时从 STL 容器中查找并删除元素

c++ - 加载相对于二进制文件的图像

c++ - 用户定义的推导指南是否涉及模板模板参数作为指南标准的模板

c++ - 使用类模板参数推导创建的临时对象的调用方法

c++ - 无法在 QtCreator 中使用 g++ 7.2 使用 c++17 功能

c++ - 从 C++ 访问 Protocol Buffer 扩展重复字段

c++ - 使用 std::launder 从指向非事件 union 成员的指针获取指向事件 union 成员的指针?

c++ - 访问 std::variant 中的公共(public)结构成员

c++ - 将 std::unique_ptr 的子类与 std::variant 一起使用

c++ - glActiveTexture 默认行为不符合预期