C++ 函数应该如何接受*lambda*参数,即常量和引用性?

C++ 函数应该如何接受*lambda*参数,即常量和引用性?,c++,function,c++11,functional-programming,std,C++,Function,C++11,Functional Programming,Std,以下各项的行为如何不同 我不清楚const对函数参数有什么影响,在这种情况下,按值传递、按引用传递或按右值引用传递会有什么区别 注意,我理解按值传递和按引用传递之间的区别。在std::function的特定情况下,或者更具体地说,在lambdas中,我不确定通过值传递lambda与通过引用传递lambda做了什么。通过值传递lambda意味着什么?要复制的数据是什么 对于lambdas,const和not之间是否存在实际区别 #include <functional> void f

以下各项的行为如何不同

我不清楚
const
对函数参数有什么影响,在这种情况下,按值传递、按引用传递或按右值引用传递会有什么区别

注意,我理解按值传递和按引用传递之间的区别。在std::function的特定情况下,或者更具体地说,在lambdas中,我不确定通过值传递lambda与通过引用传递lambda做了什么。通过值传递lambda意味着什么?要复制的数据是什么

对于lambdas,
const
和not之间是否存在实际区别

#include <functional>

void foo_with_func(      std::function<void()>   f) { ...; f(); ...; }
void foo_with_func(      std::function<void()>&  f) { ...; f(); ...; }
void foo_with_func(      std::function<void()>&& f) { ...; f(); ...; }
void foo_with_func(const std::function<void()>   f) { ...; f(); ...; }
void foo_with_func(const std::function<void()>&  f) { ...; f(); ...; }
void foo_with_func(const std::function<void()>&& f) { ...; f(); ...; }
经验法则: 常数参数

普通的旧数据类型,如
double、int、
char
应按值传递(复制)。它们适合于处理器寄存器,并且任何其他机制可能需要更多的处理或内存

较大的数据结构应通过常量引用传递。将较大的结构复制到堆栈上会占用大量内存并需要额外处理。传递引用意味着您引用的是现有项。传递常量引用意味着函数不会更改引用的项

可变参数

将由函数修改的参数应通过引用传递。这允许您的程序修改项目“就地”

注意:我没有使用移动语义,因此我不能建议是否使用移动语义。

经验法则: 常数参数

普通的旧数据类型,如
double、int、
char
应按值传递(复制)。它们适合于处理器寄存器,并且任何其他机制可能需要更多的处理或内存

较大的数据结构应通过常量引用传递。将较大的结构复制到堆栈上会占用大量内存并需要额外处理。传递引用意味着您引用的是现有项。传递常量引用意味着函数不会更改引用的项

可变参数

将由函数修改的参数应通过引用传递。这允许您的程序修改项目“就地”


注意:我没有使用移动语义,因此我不能建议是否使用移动语义。

考虑到建议的用法
foo\u with_func([&](){…}),

void foo_with_func(std::function&f){……;f();…}
将不会编译,因为它将非常量左值引用绑定到临时。其余的在任何合适的优化编译器中都是等价的。如果您还想用
std::function func,则通过传递常量左值引用可能比通过值传递更有效

但是,它们都不是最有效的,因为它们都会产生类型擦除成本。为了避免这些成本,编写一个模板并直接接受lambda

template<class F>
void foo_with_func(F f){ f(); }
模板
void foo_with_func(F){F();}

如果lambda通过值捕获并且复制可能很昂贵,那么您也可以使用
F&&

给定建议的用法
foo_with_func([&](){…}),

void foo_with_func(std::function&f){……;f();…}
将不会编译,因为它将非常量左值引用绑定到临时。其余的在任何合适的优化编译器中都是等价的。如果您还想用
std::function func,则通过传递常量左值引用可能比通过值传递更有效

但是,它们都不是最有效的,因为它们都会产生类型擦除成本。为了避免这些成本,编写一个模板并直接接受lambda

template<class F>
void foo_with_func(F f){ f(); }
模板
void foo_with_func(F){F();}

如果lambda按值捕获并且复制可能很昂贵,您也可以使用
F&&

您可以先搜索堆栈溢出,可能重复:可能重复:关于堆栈溢出或google Them有许多相关主题,我理解按值传递和按引用传递之间的区别。但是,在
std::function
的特定情况下,或者更具体地说是lambda,我不确定通过值传递lambda与通过引用传递lambda的区别。通过值传递lambda意味着什么?大多数与“lambda按值传递”或“lambda按引用传递”相关的问题都涉及lambda捕获。您可以先搜索堆栈溢出,可能重复:可能重复:关于堆栈溢出或google Them有许多相关主题,我理解按值传递和按引用传递之间的区别。但是,在
std::function
的特定情况下,或者更具体地说是lambda,我不确定通过值传递lambda与通过引用传递lambda的区别。通过值传递lambda意味着什么?大多数与“lambda通过值传递”或“lambda通过引用传递”相关的问题都涉及lambda捕获。啊,最后一句话帮助我理解。因此,如果lambda按值捕获,那么按值传递它将复制它捕获的所有内容。关于最后一个例子的问题,我也可以用func(const F&F){F()}
来做
foo_,以避免复制对吗?@Claudiu是的,但当然,这对
可变的
lambda不起作用。啊,最后一句话帮助我理解。因此,如果lambda按值捕获,那么按值传递它将复制它捕获的所有内容。关于上一个例子的问题,我也可以用func(const F&F)做
foo_
template<class F>
void foo_with_func(F f){ f(); }