在C++中传递回调函数参数的最佳方法

Mr.*_*C64 14 c++ templates callback parameter-passing

在C++ 中传递回调函数参数的最佳方法是什么?

我想过简单地使用模板,像这样:

template <typename Function>
void DoSomething(Function callback)
Run Code Online (Sandbox Code Playgroud)

这是例如std::sort用于比较功能对象的方式.

通过使用&&怎么样?例如:

template <typename Function>
void DoSomething(Function&& callback)
Run Code Online (Sandbox Code Playgroud)

这两种方法的优点和缺点是什么,为什么STL使用前者std::sort

Che*_*Alf 15

template <typename Function>
void DoSomething(Function&& callback)
Run Code Online (Sandbox Code Playgroud)

...使用转发引用通过引用传递,是IMHO优于函数只使用回调的情况.因为仿函数对象虽然通常很小,但可以任意大.按值传递然后会产生一些不必要的开销.

形式论证可以最终为T&,T const&T&&取决于实际的论点.


另一方面,通过引用传递一个简单的函数指针涉及额外的不必要的间接,这在原则上可能意味着一些轻微的开销.

如果怀疑这对于给定的编译器,系统和应用程序是否重要,则进行测量.


关于

"为什么STL使用前者[通过值]例如std::sort

...值得注意的是,std::sort自从C++ 98以来,在C++ 11中引入转发引用之前就已存在,所以它最初不能拥有该签名.

可能还没有足够的动力来改善这一点.毕竟,人们通常不应该解决哪个有效.但是,在C++ 17中引入了带有"执行策略"参数的额外超载.

由于这涉及可能的C++ 11更改,因此它没有被通常的理由来源所涵盖,即Bjarne Stroustrup的"C++的设计和演变".,我不知道任何确凿的答案.


使用该template<class F> void call( F )样式,您仍然可以获得"通过引用传递".简单地做call( std::ref( your callback ) ). std::ref覆盖operator()并转发给包含的对象.

通过template<class F> void call( F&& )风格,你可以写出:

template<class T>
std::decay_t<T> copy( T&& t ) { return std::forward<T>(t); }
Run Code Online (Sandbox Code Playgroud)

显式复制的东西,并强制call使用fby 的本地副本:

call( copy(f) );
Run Code Online (Sandbox Code Playgroud)

所以这两种风格主要在默认情况下的表现方式不同.



归档时间:

查看次数:

2424 次

最近记录:

8 年,11 月 前