将函数作为参数传递的最佳方法

时间:2016-04-07 00:35:22

标签: c++ c++11

在C ++中有几种方法可以将函数作为参数传递,但我想了解每种方法的优点和优点,例如,从算法中查看函数的签名:

template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

为什么std算法使用模板进行传递函数而不是std :: function?

为什么线程使用移动语义和算法功能?

template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);

PS:我无视C中用作函数指针的方式。

2 个答案:

答案 0 :(得分:5)

  

为什么std算法使用模板进行传递函数而不是std :: function?

C ++ 98中没有std::function。一种替代方法是使具有虚拟成员函数的抽象Comparator基类被具体的比较器类覆盖,但模板版本更有效,因为它避免了虚拟调度的开销;如果Compare是类类型,则operator()通常可以内联。这也是反对今天使用std::function的论据。

  

为什么线程使用移动语义和算法函数不?

C ++ 98中也没有右值引用。

很容易看出,现在我们有rvalue引用和移动语义,不允许将值移动到线程中是很愚蠢的(因为某些类型不可复制或无法有效复制)。

std::sort为什么要按比较取值?请参阅why function objects should be pass-by-value进行讨论。

答案 1 :(得分:1)

  

为什么std算法使用模板进行传递函数而不是std :: function?

不需要std::function作为排序,例如,直接调用你的comp可调用(可以是函数,函数调用运算符等),并在它退出时完成。当您创建std::function的实例时,您正在存储可调用的(可选地使用某些参数绑定)。

另一方面,

std::thread需要存储FnArgs,当它从构造函数中退出时,因为它们被新生成的线程使用。

  

为什么线程使用移动语义和算法功能?

同样,std::thread存储您传递给构造函数的数据,从而存储移动语义。另一方面,算法只是调用你的可调用而不需要存储它。

更新:

因此,如果你有一个内联函数,你可以遵循sort语义并将该函数作为模板参数传递。

否则,请使用std::function。这基本上是std::thread的作用 - 它将fn绑定到args并将其存储为共享ptr。