如何正确应用std::map

how to correctly apply std::map

我读到 std::map 通常用于映射函数的指针,但我不太明白它是如何工作的,这里是我将使用它的代码:

// here go all the functions to call

int main() {

    std::array<bool, 4> exercises;
    int chosenExercise;

    exercises.fill(false);

    do {
        std::cout << "Type the exercise's number you want to look at or type 0 to leave'.\n" << "(Available exercises go from 1 to " << exercises.size() << ".) \n";
        std::cin >> chosenExercise;

        if (chosenExercise < 0 || chosenExercise > exercises.size()) {
            std::cout << "Error.\n\n";
        }
    } while (chosenExercise < 0 || chosenExercise > exercises.size());

    if (chosenExercise == 0) {
        std::cout << "Leaving...";
    }
    else {
        exercises.at(chosenExercise - 1) = true;

        for (int i = 0; i < exercises.size(); i++) {
            if (exercises.at(i) == true) {
                // call the selected exercise's function and run it
            }
        }
    }

    system("pause>0");
}

在最后一个 if 中,程序应该找到选择了哪个练习并调用其函数。 有人知道它如何适用于这种情况吗?

首先,我建议快速回顾一下 std::map and std::function

现在,地图有一个键和一个值。通过 std::map::operator[]std::map::at(),您输入一个键,并且对值的引用是 returned。在您的情况下,键类似于 std::string ,值是 std::function 指向您想要的任何功能。现在,考虑这个例子:

#include <iostream>
#include <map>
#include <functional>

void sayHello() { std::cout << "Hello!\n"; }
void sayBye()   { std::cout << "Bye!\n";   }

int main()
{
    std::map<std::string, std::function<void()>> funcs = {
        {"hello", sayHello},
        {"bye", sayBye}
    };
    std::string inpFunc;
    std::cout << "What do you want me to say? ";
    std::cin >> inpFunc;
    try
    {
        funcs.at(inpFunc)();
    }
    catch (const std::out_of_range &)
    {
        std::cout << "I don't know how to say that!\n";
    }
}

这是您要执行的操作的一个基本示例。在我们的地图中,我们有两个 key/value 对:{"hello", sayHello}{"bye", sayBye}。希望你能得到这么多。如果不是,或许可以再看看 std::map 是如何工作的。

现在,我们得到了一个字符串的输入,它应该是我们映射中的键之一。查看 try 块内部:

funcs.at(inpFunc)();

也许(funcs.at(inpFunc))()更容易理解。使用 funcs.at(inpFunc),我们使用传递给 at 的键获得对值的引用。例如,如果这是 "hello",它将是 return sayHello。现在,the () after that is simply an overload of std::function 调用它拥有的函数。差不多就是这样。我也放了一个 try ... catch ,这样如果密钥不存在,它就会处理这种情况。


运行这个程序的几个例子:

What do you want me to say? hello
Hello!
What do you want me to say? bye
Bye!
What do you want me to say? hey
I don't know how to say that!