使用任何参数创建 std::functions 的 unordered_map?

Sai*_*rmo 3 c++ unordered-map c++11

我正在尝试创建一个无序的std::functions. 其中键是一个字符串,您将在其中查找要调用的函数,而函数是值。

我写了一个小程序:

#include <iostream>
#include <unordered_map>
#include <functional>
#include <string>

void func1()
{
  std::cout << "Function1 has been called." << std::endl;
}

int doMaths(int a)
{
  return a + 10;
}

int main()
{
  std::unordered_map<std::string,std::function<void()>> myMap;

  myMap["func1"] = func1;

}
Run Code Online (Sandbox Code Playgroud)

这编译得很好,我可以通过放置来调用该函数(但是我不确定这是否是正确的方法):

auto mapIter = myMap.find("func1");
auto mapVal = mapIter->second;
mapVal();
Run Code Online (Sandbox Code Playgroud)

然后调用该函数,但是我认为这是以创建该函数的新副本为代价的?如果我错了,请纠正我。

但是,如果我尝试这样做:myMap["doMaths"] = doMaths;由于 in 中的值myMapisstd::function<void()>>而 not ,我会收到编译器错误std::function<int(int)>>。当我这样做时,我确实得到了这个编译:myMap["doMaths"] = std::bind(doMaths,int());但是我不知道它实际上做了什么。当我尝试以与 相同的方式调用它时func1,出现编译器错误。

所以我想我有两个问题:

我如何创建一个 unordered_map 它将采用任何类型的函数作为它的值?以及如何在地图中调用该函数而不必复制该函数?

Pau*_*ers 7

正如 eerorika 所说,您可以使用std::any. 下面是一些示例代码,还显示了如何调用存储在映射中的函数指针:

#include <iostream>
#include <unordered_map>
#include <string>
#include <any>

void func1()
{
    std::cout << "Function1 has been called.\n";
}

int doMaths(int a)
{
    std::cout << "doMaths has been called, a = " << a << "\n";
    return a + 10;
}

int main()
{
    std::unordered_map<std::string,std::any> myMap;

    myMap["func1"] = func1;
    auto mapIter = myMap.find("func1");
    std::any_cast <void (*) ()> (mapIter->second) ();
    
    myMap["doMaths"] = doMaths;
    mapIter = myMap.find("doMaths");
    int result = std::any_cast <int (*) (int)> (mapIter->second) (5);
    std::cout << result;
}
Run Code Online (Sandbox Code Playgroud)

现场演示

std::any_caststd::bad_any_cast如果类型(或者,在这种情况下,函数签名)不匹配,将在运行时抛出异常。

请注意:std::any需要 C++17,请参阅:https : //en.cppreference.com/w/cpp/utility/any