2013-01-04 194 views
0

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

首先,它是安全这样存储函数吗?其次,如果是这样,语法是什么? (从地图上检索时,函数是否是一元函数或是否为空函数)。如果不是这样,那将是一个合理的选择?指针杀死了拉姆达的想法,正确&hellip;

C++ 11是可以的。

+0

@OliCharlesworth,这是一种出路!在某些时候,我希望能够隐藏这个,例如,只有一个获得地图类的方法。但我当然可以解决它。 –

+2

为什么不只是有两个容器?由于无论如何您必须进行一些检查,因此您知道如何调用函数,您还可以通过分隔两种函数来进行检查。 –

回答

5

一种替代方法是将nullary函数包装在一个包含lambda的函数中,该函数接受一个参数,对此不做任何处理,只是调用包装的函数。那么你的地图中的所有东西都是一元函数。

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

2

也许试试boost::variant

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

无论如何,这似乎是一个XY question究竟是你想要做什么?

+0

我想要一个工厂模式,其中“模子”对象(对象创建者)是无限的或一元的,并且映射通过类名称或问题域中的等价名称来键入。在创建最终对象之前,我可以在一元对象上使用std :: bind将它们变为空。 –

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

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

相关问题