比较通用集成功能:
template <class F> double integrate(F integrand);
Run Code Online (Sandbox Code Playgroud)
同
template <class F> double integrate(F& integrand);
Run Code Online (Sandbox Code Playgroud)
要么
template <class F> double integrate(const F& integrand);
Run Code Online (Sandbox Code Playgroud)
各自的优点和缺点是什么?STL使用第一种方法(按值传递),是否意味着它是最普遍的方法?
Joh*_*itb 26
函数对象通常应该很小,所以我不认为按值传递它们会明显地受到性能的影响(将它与函数在其体内的工作进行比较).如果您通过值传递,您也可以从代码分析中获益,因为by值参数是函数的本地参数,优化程序可以判断何时何时不能从functor的数据成员中加载.
如果仿函数是无状态的,那么将它作为参数传递意味着根本不需要任何成本 - 仿函数所采用的填充字节不必具有任何特定值(至少在GCC使用的Itanium Abi中).使用引用时,您始终必须传递地址.
最后一个(const T&)的缺点是在C++ 03中不适用于原始函数,因为在C++ 03中,如果尝试应用const函数类型,程序就会格式不正确(并且是SFINAE案例) ).更新近的实现const在应用于函数类型时忽略.
第二个(T&)有一个明显的缺点,你不能传递临时函子.
长话短说,除非我在具体案例中看到明显的好处,否则我通常会按值传递它们.
STL使用第一种方法(按值传递)
当然,标准库按值传递迭代器和仿函数.它们被假设(正确或错误)复制起来很便宜,这意味着如果你编写一个复制费用昂贵的迭代器或仿函数,你可能必须找到一种方法来进行优化.
但这仅仅是出于标准库使用仿函数的目的 - 大多数情况下它们都是谓词,尽管还有类似的东西std::transform.如果你正在集成一个函数,那就建议使用某种数学库,在这种情况下,我认为你可能更有可能处理带有大量状态的函数.例如,您可以有一个表示n阶多项式的类,其中n + 1个系数作为非静态数据成员.
在这种情况下,const引用可能会更好.当在标准算法中使用这样的仿函数时transform,您可以将它包装在通过指针执行间接的小类中,以确保它仍然便宜复制.
采用非const引用可能会让用户感到烦恼,因为它会阻止他们通过临时访问.