Considérez ce code :
#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;
}
Ici, on dirait que je capture a_
par valeur, mais lorsque je l'exécute sous Linux (GCC 4.6.1), ceci s'affiche :
A(13)
B()
~B()
~A()
0
Évidemment, 0 est faux, car A est déjà détruit. Cela ressemble à this
est en fait capturée et est utilisée pour rechercher this->a_
. Mes soupçons sont confirmés lorsque je change la liste de capture de [=]
a [=,a_]
. La sortie correcte est alors imprimée et la durée de vie des objets est conforme aux attentes :
A(13)
B()
~B()
13
~A()
La question :
Ce comportement est-il spécifié par la norme, défini par l'implémentation ou non défini ? Ou bien je suis fou et il s'agit de quelque chose d'entièrement différent ?