我应该按值还是按(右值)引用传递 std::function ?

Posted

技术标签:

【中文标题】我应该按值还是按(右值)引用传递 std::function ?【英文标题】:Should I pass std::function by-value or by (rvalue)-reference? 【发布时间】:2016-04-01 11:50:06 【问题描述】:

我不太明白std::function 的实例实际上包含什么。

按值传递还是按引用传递效率更高?

以下示例中的性能影响是什么?

按值:

void printStats(std::function<void(const char *)> printer);
. . .
std::string tmp;
printStats([&tmp](const char * msg) tmp += msg; );

通过右值引用:

void printStats(std::function<void(const char *)>&& printer);
. . .
std::string tmp;
printStats([&tmp](const char * msg) tmp += msg; );

【问题讨论】:

我认为简单的答案是价值,但以防万一你不知道:when to use templates over std::function 复制std::function 通常需要动态内存分配,因此有点昂贵,因此应该通过引用传递。 相关:Should I pass an std::function by const-reference? 【参考方案1】:

首先需要std::function,以避免在目标是std::reference_wrapper的函数指针的情况下分配;实现是encouraged to avoid allocation for "small" targets:

[...] 例如,f 的目标是一个对象,它只包含一个指针或对一个对象的引用和一个成员函数指针。

这意味着复制目标很大的std::function 将涉及分配和目标副本(不允许引用计数,因为目标可能具有可变状态)。但是,在您的特定情况下,副本将被省略,因为您正在使用 prvalue 临时调用您的函数。

在您的特定情况下,由于您立即调用该函数,因此您无需担心获得它的所有权,因此最好通过 const 引用来获取该函数。通过 rvalue 引用来获取它会让对函数具有现有 lvalue 或 const 引用的用户感到头疼;他们需要std::move它(在前一种情况下)或创建一个prvalue临时副本(在后一种情况下)。

【讨论】:

“鼓励”与“要求”不同。此外,引用的文本在注释中,注释不是规范的。

以上是关于我应该按值还是按(右值)引用传递 std::function ?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中,我应该按值传递参数并返回相同的变量,还是按引用传递?

复制赋值运算符应该通过 const 引用还是按值传递?

我应该在哪里更喜欢按引用传递或按值传递?

Java:按值传递还是按引用传递详细解说

Ruby 是按值传递还是按引用传递? [复制]

java的按值传递与按引用传递