【问题标题】:Is there any advantage/disadvantage to using function delegates over lambdas in a collection?在集合中使用函数委托而不是 lambda 有什么优点/缺点吗?
【发布时间】:2010-12-10 15:13:41
【问题描述】:

我在我的库开发中处于非常无聊的部分,我想基于 Windows 消息标识符和 WPARAMLPARAM 参数构建一个类。这些函数的原型很简单:

boost::shared_ptr<EventArgs>(const UINT& _id, const WPARAM& _w, const LPARAM& _l);

对于每条windows消息,我都会有这种性质的功能。

现在,我目前正在使用FastDelegate 库来执行我的代理。因此,这些都存储在地图中:

typedef fastdelegate::FastDelegate3<const UINT&, const WPARAM&, const LPARAM&, boost::shared_ptr<EventArgs> > delegate_type;
typedef std::map<int, delegate_type> CreatorMap;

当一条 Windows 消息需要创建一个 EventArg 派生类时,这是一个简单的案例,即查找适当的委托,调用它并返回新创建的实例,该实例很好地包含在 shared_ptr 中。

boost::shared_ptr<EventArgs> make(const UINT& _id, const WPARAM& _w, const LPARAM& _l) const
 {
  MsgMap::const_iterator cit(m_Map.find(_id));
  assert(cit != m_Map.end());
  boost::shared_ptr<EventArgs> ret(cit->second(_w, _l));
  return ret;
 }; // eo make

一切正常。但后来我在想,与其让所有这些代表都在身边,为什么不利用 C++0x 中的 lambdas 呢?所以,我很快就制作了以下原型:

typedef std::map<int, std::function<boost::shared_ptr<EventArgs>(const WPARAM&, const LPARAM&)> > MapType;
typedef MapType::iterator mit;

MapType map;
map[WM_WHATEVER] = [](const WPARAM& _w, const LPARAM& _l) { /* create appropriate eventargs class given parameters */ };
map[WM_ANOTHER] = ....;
// and so on

再一次,查找和调用很简单:

mit m = map.find(WM_PAINT);
boost::shared_ptr<EventArgs> e(m->second(_wParam, _lParam));
// dispatch e

以这种方式使用 lambda 是否有优势?我知道查找正确的委托/lambda 的开销是相同的(因为这两种类型的映射都以 int 为键),但我的目标是以我的 C++ 友好方式从 wndProc 发送我的消息尽可能高效。我的直觉是 lambdas 会更快,但不幸的是我缺乏理解编译器优化的经验来对此做出判断,因此我的问题在这里:) 哦,与问题的主题保持一致,有没有有什么陷阱/我没有想到的吗?

【问题讨论】:

    标签: visual-c++ lambda delegates c++11


    【解决方案1】:

    我在这里看到两个真正的区别:

    首先是如何存储回调:快速委托或 std::function。后者是基于 boost::function 的,并且 fast delegates 是专门为超越这些而设计的。但是,std::function 符合标准,而快速委托则不符合。

    另一个区别是您设置代码的方式,我在这里看到了 lambdas 的明显优势。您可以在重要的地方准确编写实际代码,无需定义仅用于特定用途的单独函数。

    如果您想要原始速度 - 快速代表可能会获胜(但您应该进行基准测试,如果这是一个参数),但如果您想要可读性和标准一致性,请使用 std::function 和 lambdas。

    【讨论】:

    • 感谢您的回复,您是对的。 fastdelegate(我以前用过)确实在性能方面非常好。但同样,正如您所指出的,使用 lambdas 我可以使用匿名函数创建一个非常易读的映射初始化,正如您还指出的那样,它服务于单一目的。正如你所说,我目前不知道性能是否会成为问题!
    猜你喜欢
    • 2010-11-01
    • 2013-07-12
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 2010-09-15
    • 2016-10-08
    • 2011-07-10
    相关资源
    最近更新 更多