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

Best way to pass function as parameter

本文关键字:最佳 方式 参数传递 函数      更新时间:2023-10-16

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

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

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

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

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

附言:我忽略了C中用作函数指针的方法。

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

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

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

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

很容易看出,既然我们有了右值引用和移动语义,那么不允许值移动到线程中是很愚蠢的(因为有些类型不可复制或不能有效地复制)。

为什么std::sort要按值取其比较器?查看为什么函数对象应该按值传递以供讨论。

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

不需要std::function,因为例如,排序直接在内部调用comp可调用(无论是函数、函数调用运算符等),并在它退出时使用它。当您创建std::function的实例时,您将存储可调用的(可选地与一些参数绑定)。

另一方面,std::function0在退出构造函数时需要存储FnArgs,因为它们被新派生的线程使用。

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

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

更新:

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

否则,请使用std::function。这基本上就是std::thread所做的——它将fnargs绑定,并将其存储为共享ptr。