&& 对 lambda 表达式有什么好处?
What is the benefit of && on a lambda-expression?
我看到的代码如下所示:
template<class Function>
void MyFunc(Function&& function) { function(...); }
此处 &&
与仅按值复制函数相比有何优势?作为参考,我使用的是 C++14。
问题来自避免复制。
想象一下:
auto lambda = [ptr = std::make_unique<int>(0)]() mutable {
std::cout << *ptr;
ptr = std::make_unique<int>(*ptr + 1); // why not?
};
MyFunc(lambda); // use it normally
MyFunc([]{ std::cout << " end"; }); // use by using a temporary lambda
lambda() // just call the function after that
如果签名是 MyFunc(Function f)
,则需要 std::move
并且调用后 lambda 将无法使用。
如果签名是 MyFunc(Function const& f)
,它将无法工作,因为 lambda 是可变的。
如果是 MyFunc(Function& f)
则临时文件将不起作用。
你基本上只剩下 MyFunc(Function&& f)
。
然而真正的问题是 "Do I need to support all these cases?"
我会说:大多数时候不会。大多数时候,按值接收 lambda 是最简单的,几乎支持所有情况。这就是STL的发展方向。
为什么?因为函数对象的完美转发真的很难做到完美,而且在大多数情况下你不能以完美泛型的方式多次调用函数。只有当我想包装它时,我才会完美地转发一个函数,想要完全避免复制,我希望函数对象被 ref 限定为临时对象。
我看到的代码如下所示:
template<class Function>
void MyFunc(Function&& function) { function(...); }
此处 &&
与仅按值复制函数相比有何优势?作为参考,我使用的是 C++14。
问题来自避免复制。
想象一下:
auto lambda = [ptr = std::make_unique<int>(0)]() mutable {
std::cout << *ptr;
ptr = std::make_unique<int>(*ptr + 1); // why not?
};
MyFunc(lambda); // use it normally
MyFunc([]{ std::cout << " end"; }); // use by using a temporary lambda
lambda() // just call the function after that
如果签名是 MyFunc(Function f)
,则需要 std::move
并且调用后 lambda 将无法使用。
如果签名是 MyFunc(Function const& f)
,它将无法工作,因为 lambda 是可变的。
如果是 MyFunc(Function& f)
则临时文件将不起作用。
你基本上只剩下 MyFunc(Function&& f)
。
然而真正的问题是 "Do I need to support all these cases?"
我会说:大多数时候不会。大多数时候,按值接收 lambda 是最简单的,几乎支持所有情况。这就是STL的发展方向。
为什么?因为函数对象的完美转发真的很难做到完美,而且在大多数情况下你不能以完美泛型的方式多次调用函数。只有当我想包装它时,我才会完美地转发一个函数,想要完全避免复制,我希望函数对象被 ref 限定为临时对象。