【问题标题】:map containing std::function<T()> and std::function<T(int)>包含 std::function<T()> 和 std::function<T(int)> 的映射
【发布时间】:2013-01-04 21:15:58
【问题描述】:

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

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

C++11 没问题。

【问题讨论】:

  • @OliCharlesworth,这是一条出路!在某些时候,我希望能够隐藏这一点,例如,地图类中只有一个 get 方法。但我当然可以解决它。
  • 为什么不只有两个容器?由于无论如何您都必须进行一些检查,以便知道如何调用该函数,因此您不妨将这两种函数分开来进行检查。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    也许试试boost::variant

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

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

    【讨论】:

    • 我想要一个工厂模式,其中“stamper”对象(对象创建者)是空的或一元的,并且映射由类名或问题域中的等效名称作为键。在创建最终对象之前,我可以在一元对象上使用 std::bind 将它们变成空值。
    【解决方案3】:

    空的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&lt;0&gt;get&lt;1&gt;。这样做的好处是,如果您选择在模板中访问两者中的哪一个,它可以静态选择 0 或 1 并使用通用代码。如果您不需要这个,只需两个std::maps。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      相关资源
      最近更新 更多