如何在C++中创建将函数与参数相关联的 Map?

How to create a Map in C++ that associates functions to parameters?

本文关键字:参数 关联 Map 函数 C++ 创建      更新时间:2023-10-16

考虑要按顺序调用 100 个函数。

我想创建一个包含函数指针和函数参数的映射,以便我可以迭代映射并使用关联的参数调用每个函数。

参数具有不同的类型、arity 和返回类型。是否可以在C++中实现这样的地图?

伪代码

for function in map
// call the function with the arguments from the map
function(map[function]) 

正如评论中所述,这个问题太宽泛了。因此,有太多可能的解决方案。另外,我真的想知道为什么你需要这种功能映射。我敢肯定,如果您解释了您的问题,许多人会建议您使用另一种解决方案。

也就是说,我觉得这个主题很有趣,并试图为您的问题实施一个可能的解决方案。

由于主题非常广泛,问题不够具体,我不得不做出一些决定(也基于评论):

  • 我使用set而不是map,因为我不知道地图的(键,值)应该是什么。
  • 我只是打印出结果(假设结果是可打印的),因为我不知道如何处理结果。
  • 我没有使用函数指针,而是使用了函数对象。
  • 由于我无法完全理解伪代码,因此这些函数由调用函数调用。

修改下面的示例代码应该可以让您获得真正想要的内容。下面的代码只是您可能需要哪种成分的示例。

泛型函数和集合

您只能在set(或map)中保存一种类型,因此您需要一些GenericFunction类:

class GenericFunction
{
public:
virtual ~GenericFunction() = default;
virtual void invoke() const = 0; // the method to invoke the function
};

现在,您可以定义一个set,其中包含指向GenericFunction对象的指针:

std::set<GenericFunction*> myFcts;

特定功能类

接下来,让我们实现派生自GenericFunction类的特定函数类。此类的目标是存储您选择的函数和参数,并提供invoke函数的实现。

#include <iostream>
#include <tuple>
template <typename Fct, typename ... Args>
class MyFct : public GenericFunction
{
public:
MyFct(Fct fct, Args&& ... args) :
_fct { std::move(fct) },
_args { std::forward<Args>(args)... }
{}
void invoke() const override { std::cout << std::apply(_fct,_args) << std::endl; }
private:
Fct _fct;
std::tuple<Args ...> _args;
};

测试:求和函数

为了测试,让我们编写一个简单的 sum 函数:

template <typename T>
auto sum(T a)
{
return a;
}
template <typename F, typename ... R>
auto sum(F first, R ... rest)
{
return first + sum(rest...);
}

主要功能

我们现在可以使用上面的代码,如下所示:

#include <set>
int main()
{
// function wrapper
auto sum_wrapper = [](auto&&... args)
{
return sum(std::forward<decltype(args)>(args)...);
};
// create a specific function
MyFct myf1(sum_wrapper, 1, 2.33/*, add the args of your choice*/);
// create another specific function        
MyFct myf2(sum_wrapper, 10, 2.33/*, add the args of your choice*/);
// create the set
std::set<GenericFunction*> myFcts { &myf1, &myf2 };
// call the functions
for (const auto& f : myFcts)
f->invoke();
return 0;
}