Ho una discreta quantità di codice che si basa sulla cattura di un shared_from_this()
quando si utilizza un'espressione lambda come un callback per assicurare che la mia istanza rimane in vita:C++: È possibile ottimizzare una cattura esplicita lambda non utilizzata?
std::shared_ptr<Thing> self = shared_from_this();
auto doSomething = [this, self]()
{
// various statements, none of which reference self, but do use this
}
Quindi la domanda è: Dal momento che io non sono REFERENCING self
all'interno il corpo lambda, è un compilatore conforme che ha permesso di ottimizzare la cattura?
Si consideri il seguente programma:
#include <functional>
#include <iostream>
#include <memory>
std::function<void()> gFunc;
struct S : std::enable_shared_from_this<S>
{
void putGlobal()
{
auto self = shared_from_this();
gFunc = [self] { };
}
};
int main()
{
auto x = std::make_shared<S>();
std::cout << x.use_count() << std::endl;
x->putGlobal();
std::cout << x.use_count() << std::endl;
}
l'output è:
1
2
Questo indica che g++-4.7.1
non ottimizza la cattura di distanza (né clang-3.1
).
Questo sembra contraddire [questa risposta] (http://stackoverflow.com/questions/6181464/c11-lambda-capture-semantics), che dice che se è inutilizzato ODR, allora non viene effettivamente catturato. – GManNickG
@GManNickG: la differenza è quella di acquisizione implicita ('[=]') e * esplicita * cattura ('[someNameHere]'). L'acquisizione implicita richiede elementi ODR usati. L'acquisizione esplicita no. –
@NicolBolas: Gotcha. Un'entità viene catturata implicitamente se e solo se si utilizza ODR. A quel punto, è nella stessa barca delle entità esplicitamente catturate. Grazie. – GManNickG