Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建带有任何参数的std::函数的无序_映射?_C++_C++11_Unordered Map - Fatal编程技术网

C++ 创建带有任何参数的std::函数的无序_映射?

C++ 创建带有任何参数的std::函数的无序_映射?,c++,c++11,unordered-map,C++,C++11,Unordered Map,我正在尝试创建std::functions的无序映射。其中,键是一个字符串,您将在其中查找要调用的函数,函数是值 我写了一个小程序: #include <iostream> #include <unordered_map> #include <functional> #include <string> void func1() { std::cout << "Function1 has been called." <<

我正在尝试创建
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;

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

但是,如果我尝试这样做:
myMap[“doMaths”]=doMaths我得到一个编译器错误,因为
myMap
中的值是
std::function>
而不是
std::function>
。当我编译时,我确实编译了它:
myMap[“doMaths”]=std::bind(doMaths,int())但是我不知道它实际上做了什么。当我试图以与
func1
相同的方式调用它时,我得到了一个编译器错误

所以我想我有两个问题:


我如何创建一个无序的_映射,它将以任何类型的函数作为其值?我如何在映射中调用函数而不必复制函数

正如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;
}
#包括
#包括
#包括
#包括

std::any_cast
将在运行时抛出一个
std::bad_any_cast
异常,如果类型(或者在本例中是函数签名)不匹配


请注意:
std::any
需要C++17,请参阅:

如果您知道您的函数类型是
std::function
,请将其放在
std::unordered\u映射中,然后在那里查找


如果您知道函数的类型是
std::function
,请将其放入
std::unordered_map
,然后在那里查找

如果您不知道函数的类型,则无法使用它,因此将其存储在映射中也是无用的


如果有多种类型的函数,则也有多种映射。变量模板(或带有静态映射变量的函数模板)有助于在不复制任何代码的情况下拥有任意数量的此类映射。当然,这样你只能拥有一张全球地图。一个能够管理这样一组映射的类可能会涉及更多,但只涉及一点点。

就像Paul说的,但是使用
std::function
语法。您可以使用它在映射中放置具有任何签名的函数,甚至lambdas:D

#include <vector>
#include <iostream>
#include <functional>
#include <map>
#include <any>

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

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

  map["foo"] = std::function<int(int)>([](int a) { return a * 2; });

  map["bar"] = std::function<int(int, int)>([](int a, int b) { return a + b; });

  map["maths"] = std::function<int(int)>(doMaths);

  int a = std::any_cast<std::function<int(int)>>(map["foo"])(4);

  int b = std::any_cast<std::function<int(int, int)>>(map["bar"])(4, 5);

  int c = std::any_cast<std::function<int(int)>>(map["maths"])(5);

  std::cout << a << " " << b << " " << c <<std::endl;
}
#包括
#包括
#包括
#包括
#包括
int doMaths(int a)
{

std::cout您希望如何使用它?您如何知道
myMap[name]
应使用零个、一个或多个参数调用?您可以使用
std::unordered_map
。我想我应该知道需要调用哪个函数。我正在试图找到正确的词语来解释自己。假设我有一个函数需要在类和UI中更新。它们都有一个名为
的函数>updateValue(int)
。它们不是调用
ui->updateValue(int)
class->updateValue(int)
而是包装在另一个类中,该类将具有更新两个值的函数。我不知道我是否解释得足够清楚@Jarod42@Sailanarmo示例:@Sailanarmo
audo-mapIter=myMap.find(“doMaths”);int result=std::any_cast(mapIter->second)(42);
,请参阅:非常感谢!这将极大地帮助我。@Sailanarmo Mypleasure@nm如果您阅读了OP上面的评论,我认为他很高兴在从映射中检索到他计划调用的函数的函数签名(无论是好是坏)。
#include <vector>
#include <iostream>
#include <functional>
#include <map>
#include <any>

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

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

  map["foo"] = std::function<int(int)>([](int a) { return a * 2; });

  map["bar"] = std::function<int(int, int)>([](int a, int b) { return a + b; });

  map["maths"] = std::function<int(int)>(doMaths);

  int a = std::any_cast<std::function<int(int)>>(map["foo"])(4);

  int b = std::any_cast<std::function<int(int, int)>>(map["bar"])(4, 5);

  int c = std::any_cast<std::function<int(int)>>(map["maths"])(5);

  std::cout << a << " " << b << " " << c <<std::endl;
}