当使用模板支持functor作为参数时,我应该使用什么限定符?

Art*_*ind 7 c++ templates functor function-object c++11

考虑以下代码:

template<class F>
void foo1(F f) { f(); }

template<class F>
void foo2(F const& f) { f(); }

template<class F>
void foo3(F&& f) { f(); }
Run Code Online (Sandbox Code Playgroud)

foo我应该使用哪个版本?foo1这是我在"野外"看到的最多,但我担心它可能会引入我不想要的副本.我有一个很复杂的自定义仿函数,所以我想避免这种情况.目前我倾向于foo3(因为foo2不允许变异的算子),但我不确定其含义.

我的目标是C++ 11.

Joh*_*ard 7

其实我更喜欢foo3foo1(虽然机构应std::forward<F>(f)();)

foo3将导致类型F推断为允许您完全转发参数的类型,因为引用折叠.这很有用,因为默认情况下你不会复制任何东西,并且如果你决定将仿函数转发给想要它的副本的东西,它可以保持值类别(左值与右值).

一般来说,foo1如果你的函数要存储它自己的仿函数副本,那么第一个form()就可以了,但是第三个form(foo3)更适合转发(使用)参数.

我还推荐Scott Meyers关于通用引用的优秀帖子,以及相关的Stack Overflow问题.

  • @super我不确定你是否真的应该转发(除非你从不多次调用参数).如果`operator()`没有单独的`&&`-qualified重载,那么转发什么都不做.但是如果有这样的溢出(虽然我从来没有见过有人这样做)并且如果函数作为右值传递并且使用`std :: forward`移动,那么调用`operator()`可以将其保留为未指定的state,如果你要再次调用`operator()`那就不好了. (2认同)