如何在c++中将具有不同参数的函数放入映射中

How can i put function with different parameters into map in c++?

本文关键字:函数 参数 映射 c++      更新时间:2024-09-23

我需要设计一个映射,保存我将来可能使用的所有函数。

所有函数都将CCD_ 1作为其返回值。

并且所有功能共享一个公共参数CCD_ 2

所以我把地图定义为:

typedef std::function<double(const std::vector<float>&)> func;
std::unordered_map<std::string, func> f_map;

例如。如果我有一个函数看起来像:

double func1(const std::vector<float>& v) {
return 0.; // just a demo
}

我可以把它放在这样的地图上:

f_map.emplace("2015", static_cast<double(*)(const std::vector<float>&)>(func1));

自从我测试后就没问题了。

但问题是:

我还有一些类似的功能:

double func2(int a, const std::vector<float>& v) {
return 0.; // just for demo
}

如何在地图中输入这种函数?

std::如果我这样做,绑定就不起作用:

f_map.emplace("2000", static_cast<double(*)(const std::vector<float>&)>(std::bind(func2, 1)));

你能帮忙吗?

你能给我关于如何更好地将功能保存到地图中的建议吗,非常感谢

您所问的基本上与相同

如何将intfloat存储在映射中并平等使用它们?

具有不同参数的函数是完全不同的。地图只能容纳一种类型。假设你得到函数";2019";,你或编译器怎么知道它是什么样的函数?

有几种方法可以解决这个问题。本质是让它们是相同的类型。有了std::bind,你就走上了正轨。使用参数绑定的正确方法是使用std::placeholders

假设我们有这个函数double DoThing(int num, std::vector<float>& vec),并希望填写第一个参数,但保留第二个参数供以后使用。我们可以做到:

mymap.emplace("2000", std::bind(&DoThing, 123, std::placeholders::_1));

您可以随意移动占位符,也可以添加其他占位符。如果你存储了对象绑定返回,然后再把它拿回来,你可以这样调用它:

mymap["2000"](vec);  //will call  DoThing(123, vec)

此外。std::bind返回一个对象,该对象包含指向DoThing的函数指针以及您预先填充的任何值。像您所做的那样将其转换为函数指针是不可能的。该对象在这里不是问题,因为映射包含的类型double0也具有存储功能,并且以后能够正确调用该对象。

类似地,您可以使用lambda来实现与绑定相同的效果:

mymap.emplace("2000", [](std::vector<float>& vec){ return DoThing(123, vec); });

其他可能性包括联合/变体或其他可能棘手的问题。尽管如果你不知道如何使用这些方法,这些方法只会让你的代码变得更复杂,所以我不推荐这些方法。

避免类型转换更好更安全。第一个模板[1]在没有static_cast的情况下是有效的。

您应该在占位符[2]的帮助下通知std::bind将未绑定的参数放置在哪里。命名空间CCD_ 13的CCD_。

如果使用不捕获lamba表达式,则可以存储指向函数的指针。指针占用的字节数少于std::function对象。参见[3]。

#include <functional>
#include <string>
#include <unordered_map>
double func1(const std::vector<float>&) {
return 0.; // just a demo
}
double func2(int, const std::vector<float>&) {
return 0.; // just for demo
}
int main() {
using namespace std::placeholders;
typedef std::function<double(const std::vector<float>&)> func;
std::unordered_map<std::string, func> f_map;

f_map.emplace("2015", func1);                    // [1]
f_map.emplace("2000", std::bind(func2, 1, _1));  // [2]
// [3]
typedef double(*pfunc)(const std::vector<float>&);
std::unordered_map<std::string, pfunc> f_map2;

f_map2.emplace("2015", func1);
f_map2.emplace("2000", [](const std::vector<float>&v) { return func2(1, v); });
}