考虑以下代码:
#include <memory>
#include <iostream>
class A
{
public:
A(int data) : data_(data)
{ std::cout << "A(" << data_ << ")" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
void a() { std::cout << data_ << std::endl; }
private:
int data_;
};
class B
{
public:
B(): a_(new A(13)) { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B()" << std::endl; }
std::function<void()> getf()
{
return [=]() { a_->a(); };
}
private:
std::shared_ptr<A> a_;
};
int main()
{
std::function<void()> f;
{
B b;
f = b.getf();
}
f();
return 0;
}
在这里看起来我是按值捕获了 a_
的共享指针,但是当我在 Linux 上运行它(GCC 4.6.1),会打印出这个:
A(13)
B()
~B()
~A()
0
显然,0是错误的,因为A已经被销毁了。看起来this
实际上被捕获并用于查找this->a_
。当我将捕获列表从[=]
更改为[=,a_]
时,我的怀疑得到了确认。然后正确的输出被打印出来,对象的生命周期也符合预期:
A(13)
B()
~B()
13
~A()
问题:
这种行为是由标准规定的,实现定义的,还是未定义的?或者我疯了,它完全不同?
this
。如果指针只是神奇地成为成员解引用,那将是令人惊讶的!不过这是一个好问题,并且对于孩子们不要轻率地使用懒惰捕获[=]
/[&]
是一个很好的警告。 - Kerrek SB