Why the switch statement cannot be applied on strings?

前端 未结 20 2809
离开以前
离开以前 2020-11-22 03:58

Compiling the following code and got the error of type illegal.

int main()
{
    // Compilation error - switch expression of type illegal
    sw         


        
20条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-22 04:30

    std::map + C++11 lambdas pattern without enums

    unordered_map for the potential amortized O(1): What is the best way to use a HashMap in C++?

    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main() {
        int result;
        const std::unordered_map> m{
            {"one",   [&](){ result = 1; }},
            {"two",   [&](){ result = 2; }},
            {"three", [&](){ result = 3; }},
        };
        const auto end = m.end();
        std::vector strings{"one", "two", "three", "foobar"};
        for (const auto& s : strings) {
            auto it = m.find(s);
            if (it != end) {
                it->second();
            } else {
                result = -1;
            }
            std::cout << s << " " << result << std::endl;
        }
    }
    

    Output:

    one 1
    two 2
    three 3
    foobar -1
    

    Usage inside methods with static

    To use this pattern efficiently inside classes, initialize the lambda map statically, or else you pay O(n) every time to build it from scratch.

    Here we can get away with the {} initialization of a static method variable: Static variables in class methods , but we could also use the methods described at: static constructors in C++? I need to initialize private static objects

    It was necessary to transform the lambda context capture [&] into an argument, or that would have been undefined: const static auto lambda used with capture by reference

    Example that produces the same output as above:

    #include 
    #include 
    #include 
    #include 
    #include 
    
    class RangeSwitch {
    public:
        void method(std::string key, int &result) {
            static const std::unordered_map> m{
                {"one",   [](int& result){ result = 1; }},
                {"two",   [](int& result){ result = 2; }},
                {"three", [](int& result){ result = 3; }},
            };
            static const auto end = m.end();
            auto it = m.find(key);
            if (it != end) {
                it->second(result);
            } else {
                result = -1;
            }
        }
    };
    
    int main() {
        RangeSwitch rangeSwitch;
        int result;
        std::vector strings{"one", "two", "three", "foobar"};
        for (const auto& s : strings) {
            rangeSwitch.method(s, result);
            std::cout << s << " " << result << std::endl;
        }
    }
    

提交回复
热议问题