在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中用作函数指针的方式。
答案 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
需要存储Fn
和Args
,当它从构造函数中退出时,因为它们被新生成的线程使用。
为什么线程使用移动语义和算法功能?
同样,std::thread
存储您传递给构造函数的数据,从而存储移动语义。另一方面,算法只是调用你的可调用而不需要存储它。
更新:
因此,如果你有一个内联函数,你可以遵循sort
语义并将该函数作为模板参数传递。
否则,请使用std::function
。这基本上是std::thread
的作用 - 它将fn
绑定到args
并将其存储为共享ptr。