0

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

首先,以这种方式存储函数是否安全?其次,如果是这样,语法是什么?(从地图中检索到该函数是一元还是零元时,将知道它。)如果以上都不是,那么合理的替代方案是什么?指针扼杀了 lambda 的想法,对吧……

C++11 没问题。

4

3 回答 3

5

一种替代方法是将 nullary 函数包装在一个包装器 lambda 中,该包装器 lambda 接受一个参数,对它不做任何事情,并简单地调用被包装的函数。那么地图中的所有内容都是一元函数。

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

于 2013-01-04T21:18:41.233 回答
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";
}

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

Aboost::variant也有效(映射到variant0ary 或 1ary 函数的 a)。您还可以在带有枚举(复制)的 a 中使用 C++11 union(注意它没有默认构造函数或复制构造函数,除非您提供一个) - 基本上是一个 ghetto 。structunionboost::variant

于 2013-01-04T22:03:22.897 回答
2

也许试试boost::variant

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

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

于 2013-01-04T21:18:42.487 回答