多个枚举值的开关/机箱



我有两个值,每个值来自不同的枚举。我想检查这两者的允许组合,如果未找到,则执行默认操作。我可以以某种方式对这两个值进行切换/大小写吗?我想避免多个 if/else 语句或遵循位掩码模式的枚举,仅仅是因为我认为它们在代码中不如开关/大小写漂亮。

对于了解 Python 的人来说,我基本上想要一个 Python 代码的解决方案C++:

val1 = "a"
val2 = 2
actions = {
    ("a", 1): func1,
    ("b" ,1): func2,
    ("a" ,2): func3,
    ("b" ,2): func4
}
action = actions.get((val1, val2), default_func)()
action()

std::map std::pair键和std::function值浮现在脑海中。

更准确地说,您可以将函数对象映射到特定的枚举对象对。下面是一个示例:

#include <map>
#include <functional>
#include <iostream>
enum class Enum1
{
    a, b, c
};
enum class Enum2
{
    one, two, three
};
int main()
{
    auto const func1 = [] { std::cout << "func1n"; };
    auto const func2 = [] { std::cout << "func2n"; };
    auto const func3 = [] { std::cout << "func3n"; };
    auto const func4 = [] { std::cout << "func4n"; };
    auto const default_func = [] { std::cout << "defaultn"; };
    std::map<std::pair<Enum1, Enum2>, std::function<void()>> const actions =
    {
        {{ Enum1::a, Enum2::one }, func1 },
        {{ Enum1::b, Enum2::one }, func2 },
        {{ Enum1::a, Enum2::two }, func3 },
        {{ Enum1::b, Enum2::two }, func4 }
    };
    auto const val1 = Enum1::a;
    auto const val2 = Enum2::two;
    auto const action_iter = actions.find({ val1, val2 });
    auto const action = action_iter != actions.end() ? action_iter->second : default_func;
    action();
}

我可以以某种方式对这两个值进行切换/外壳吗?

不,你不能。 switch仅适用于一个值。如果无法将两个值转换为一个整数值,则必须使用其他方法。以下是我能想到的几种方法。

  1. 您可以使用级联if-else语句。

    if ( val1 == "a" && val2 == 1 )
    {
       func1();
    }
    else if ( val1 == "b" && val2 == 1 )
    {
       func2();
    }
    else if ( val1 == "a" && val2 == 2 )
    {
       func3();
    }
    else if ( val1 == "b" && val2 == 2 )
    {
       func4();
    }
    
  2. 您也可以使用 map .

    using map_type = std::map<std::pair<decltype(val1), decltype(val2)>, decltype(func1)>;
    map_type functions = {{ {"a", 1}, func1}, { {"a", 1}, func1}, { {"a", 1}, func1}, { {"a", 1}, func1}};
    auto iter = functions.find(std::make_pair(val1, val2));
    if ( iter != functions.end() )
    {
       iter->second();
    }
    

最新更新