包含 std::function<T()> 和 std::function<T(int)的映射>

map containing std::function<T()> and std::function<T(int)>

本文关键字:gt function std lt 映射 包含 int      更新时间:2023-10-16

我想有一个单一的映射映射字符串键到std::function<T()>std::function<T(int)>(但不是两个给定的键)。我得到一个编译错误,似乎没有一个模板的std::function<T(...)>。我希望能够使用lambdas作为值。

首先,以这种方式存储函数是否安全?其次,如果是的话,语法应该是什么?(当从映射中检索到该函数时,就知道它是一元函数还是无元函数。)如果以上都不是,那么什么才是合理的选择呢?指针扼杀了lambda的想法,对& help;

一种替代方法是将虚值函数包装在包装器lambda中,该包装器lambda接受一个参数,不处理它,只调用包装的函数。那么,映射中的所有内容都是一元函数。

当然,如果你在检索时知道函数的类型(我猜你必须知道,否则它是无用的!),那么为什么不使用两个映射呢?

试试boost::variant ?

std::map<std::string, boost::variant<std::function<T()>, std::function<T(int)> > >

无论如何,这似乎是一个XY问题。到底是什么你想做的?

std::function没有那么重。你可以直接映射到一个包含这两种元素的结构体。你知道哪个是有效的,所以只访问那个。

如果你的模板代码需要同时操作这两个对象,而不需要将其中任何一个作为参数传入:

#include <string>
#include <functional>
#include <map>
#include <tuple>
#include <iostream>
#include <math.h>
template<typename T>
using my_maps = std::tuple< std::map<std::string, std::function<T()>>, std::map<std::string, std::function<T(int)>>>;

int main() {
  my_maps<double> maps;
  std::get<0>(maps)["pi"] = [](){ return 3.14; };
  std::get<1>(maps)["e^"] = [](int x){ return pow( 2.7, x ); };
  std::cout << std::get<1>(maps)["e^"](2) << "n";
  std::cout << std::get<0>(maps)["pi"]() << "n";
}

有两个映射,不同的是访问get<0>get<1>。这样做的好处是,如果要在模板中选择访问哪一个,它可以静态地选择0或1,并使用通用代码。如果你不需要这个,只需要两个std::map

boost::variant也可以(映射到0或1函数的variant)。您还可以使用c++ 11的union(注意,它将没有默认构造函数,或复制构造函数,除非您提供一个)在struct中使用enum(复制union)——基本上是一个贫民窟的boost::variant