我看到lambda表达式的C 11文档(
http://en.cppreference.com/w/cpp/language/lambda)支持按值和引用捕获但不支持右值引用.我能找到的最接近的SO问题是:
How to capture a unique_ptr into a lambda expression?,但似乎我的用例不需要使用std :: bind.
码
#include <iostream>
#include <memory>
class Foo
{
public:
explicit Foo(int value = 0) : mValue(value) {}
// The following items are provided just to be explicit
Foo(Foo &&other) = default;
Foo &operator=(Foo &&other) = default;
Foo(const Foo &other) = delete;
Foo &operator=(const Foo &other) = delete;
~Foo() {}
int mValue;
};
void bar(std::unique_ptr<Foo> f)
{
std::cout << "bar: " << std::dec << f->mValue << "\n";
}
int main()
{
{
std::unique_ptr<Foo> f(new Foo(22));
std::cout << "main: " << std::hex << f.get() << "\n";
// Call the bar function directly (requires using std::move)
bar(std::move(f));
std::cout << "main: " << std::hex << f.get() << "\n";
}
{
std::unique_ptr<Foo> f(new Foo(99));
std::cout << "main: " << std::hex << f.get() << "\n";
// Lamda expression captures 'f' by reference and then calls the bar function (again, requires using std::move)
auto fn = [&f](){ bar(std::move(f)); };
fn(); // Execute the closure
std::cout << "main: " << std::hex << f.get() << "\n";
}
return 0;
}
示例输出
main: 0x92e010
bar: 22
main: 0
main: 0x92e010
bar: 99
main: 0
通过检查输出,看起来这个程序运行正常(即,观察到的结果是我所期望的.但是,我有以下问题.
问题
>使用闭包等效于直接调用bar函数的代码吗?
>我明确要求,因为有关lambda表达式的文档(请参阅问题的开头)没有说明在捕获的引用上使用std :: move的任何内容(即,我想确保这不会违反未定义的行为或类似的不良结果).
>如果第一个问题的答案是“你不能在捕获的引用上使用std :: move”,那么正确的方法是什么(例如,std :: bind解决方案等)?
最佳答案
Is using the closure equivalent to the code that calls the bar function directly?
是的,它们在此代码中是等效的.捕获的引用并不是我能想到的任何特殊方式:只要f在范围内并且可以移动,就可以完全定义行为.