【问题标题】:std::function vs std::function& as a function argument [duplicate]std::function vs std::function& 作为函数参数[重复]
【发布时间】:2015-04-29 16:34:15
【问题描述】:

考虑以下三个函数,

func1(std::function<size_t(...) > f, ...);
func2(std::function<size_t(...) >& f );
func3(const std::function<size_t(...)> &f);  

对于通过值/复制构造函数传递的任何其他类型的参数,通过引用传递和通过 const 引用传递具有明确的上下文,并且它们的用例是众所周知的。

对于function&lt;&gt; 对象,例如通过 const 引用节省时间(例如调用潜在的复制构造函数)或空间(无需将整个函数对象传递到堆栈)?首先,函数对象有多大才值得通过 const 引用传递?我的猜测是它大概是指针的大小 - 这是正确的吗?

【问题讨论】:

  • 我一直觉得std::function 实际上是相当重量级的。例如,它必须能够包含成员函数指针的类实例。它可能会使用捕获的变量包装绑定表达式或 lambda,这显然需要存储需要复制的额外状态(除非它是堆分配的,我想)。
  • 否:复制一个函数对象(例如,持有一个 lambda)可能非常昂贵。
  • @Cameron:这取决于它包装了什么类型的函数对象,以及它是如何实现的。如果它包装了一个小的(甚至是空的)对象,并且优化为不动态分配它,那么它可以非常轻量级。

标签: c++ c++11


【解决方案1】:

让我们使用 gcc 4.9 并检查一下:

cout << sizeof(int(*)(double, double)) << endl;
cout << sizeof(function<int(double, double)>) << endl; 

输出:

8
32

当然,可调用对象的大小大于指针大小,您可能会受益于通过 const 引用传递它。但是,这是一个好主意,前提是您可以保证您通过 const 引用传递的对象(无论它是否以 std::function&lt;&gt; 开头)只要您打算使用它就一直存在。

【讨论】:

    【解决方案2】:

    对于function&lt;&gt; 对象,例如通过 const 引用节省时间(例如调用潜在的复制构造函数)或空间(无需将整个函数对象传递到堆栈)?

    也许吧。你必须测量它。

    首先,函数对象有多大才值得通过 const 引用传递?

    这取决于实现。你必须测量它。

    我的猜测是它大概是指针的大小 - 这是正确的吗?

    鼓励实现使用“小对象优化”,以便将小函数对象存储在function 对象中,而不是动态分配。在这种情况下,它将是该对象的大小(或略大于该对象)。否则,它将是(或略大于)指向动态对象的指针的大小。

    【讨论】:

      猜你喜欢
      • 2015-03-09
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-19
      • 2018-06-07
      相关资源
      最近更新 更多