当使用模板支持仿函数作为参数时,我应该使用什么限定符?
When using templates to support functor as arguments, what qualifier should I use?
考虑这段代码:
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(); }
我应该使用 foo
的哪个版本? foo1
是我看到最多的 "in the wild" 但我担心它可能会引入我不想要的副本。我有一个自定义仿函数,复制起来有点麻烦,所以我想避免这种情况。目前我倾向于 foo3
(因为 foo2
不允许变异函子)但我不确定其含义。
我的目标是 C++11。
我实际上更喜欢 foo3
而不是 foo1
(虽然正文应该是 std::forward<F>(f)();
)
foo3
将导致类型 F
被推导为允许您完美转发由于 reference collapsing 引起的参数的类型。这很有用,因为默认情况下您不会复制任何内容,并且如果您决定要将仿函数转发给确实需要它的副本的对象,则可以维护值类别(左值与右值)。
一般来说,如果您的函数要存储它自己的仿函数副本,第一种形式 (foo1
) 没问题,但第三种形式 (foo3
) 更适合转发 (使用)参数。
我还推荐 Scott Meyers 关于 universal references, as well as this related Stack Overflow question 的精彩 post。
考虑这段代码:
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(); }
我应该使用 foo
的哪个版本? foo1
是我看到最多的 "in the wild" 但我担心它可能会引入我不想要的副本。我有一个自定义仿函数,复制起来有点麻烦,所以我想避免这种情况。目前我倾向于 foo3
(因为 foo2
不允许变异函子)但我不确定其含义。
我的目标是 C++11。
我实际上更喜欢 foo3
而不是 foo1
(虽然正文应该是 std::forward<F>(f)();
)
foo3
将导致类型 F
被推导为允许您完美转发由于 reference collapsing 引起的参数的类型。这很有用,因为默认情况下您不会复制任何内容,并且如果您决定要将仿函数转发给确实需要它的副本的对象,则可以维护值类别(左值与右值)。
一般来说,如果您的函数要存储它自己的仿函数副本,第一种形式 (foo1
) 没问题,但第三种形式 (foo3
) 更适合转发 (使用)参数。
我还推荐 Scott Meyers 关于 universal references, as well as this related Stack Overflow question 的精彩 post。