包含std :: function <t()>和std :: function <t(int)> </t(int)> </t()>的地图

时间:2013-01-04 21:15:59

标签: c++ map c++11 stdmap std-function

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

首先,以这种方式存储功能是安全吗?其次,如果是这样,语法是什么? (当从地图中检索到函数时,函数是一元函数还是无效函数。)如果不是上述函数,那么什么是合理的替代方案?指针杀死了lambda的想法,对吧......

C ++ 11没问题。

3 个答案:

答案 0 :(得分:5)

一种替代方法是将一个nullary函数包装在一个包装器lambda中,它接受一个参数,对它没有任何作用,只是调用包装函数。然后地图中的所有内容都是一元函数。

当然,如果你在检索时知道这个函数是什么类型的(我想你必须这样做,否则它就没用了!),那么为什么不使用两个地图?

答案 1 :(得分:2)

也许试试boost::variant

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

无论如何,这似乎是XY question。您想要做什么完全

答案 2 :(得分:2)

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 s。

boost::variant也有效(映射到0ary或1ary函数的variant)。您还可以在union中使用C ++ 11 struct(注意它没有默认构造函数或复制构造函数,除非您提供一个构造函数)并使用枚举(执行副本) union) - 基本上是一个贫民区boost::variant