C ++: Можно ли оптимизировать неиспользуемый лямбда-явный захват?

У меня есть приличное количество кода, который опирается на захват shared_from_this() при использовании лямбда-выражения в качестве обратного вызова, чтобы убедиться, что мой экземпляр остается в живых:

std::shared_ptr<Thing> self = shared_from_this();
auto doSomething = [this, self] ()
{
// various statements, none of which reference self, but do use this
}

Итак, вопрос: так как я не ссылаюсь self внутри лямбда-тела позволяет ли совместимый компилятор оптимизировать захват?


Рассмотрим следующую программу:

#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;
}

Выход:

1
2

Это указывает на то, что g++-4.7.1 не оптимизирует захват (и не clang-3.1).

23

Решение

Стандарт гарантирует, что полученные значения не будут оптимизированы (согласно §5.1.2 / 14):

Объект захватывается копией, если он захвачен неявно, а по умолчанию — = или это явно
захваченный
с захватом, который не включает в себя &, Для каждого объекта, захваченного копией, безымянный
член статических данных объявлен в типе замыкания.
Порядок объявления этих членов не уточняется.
Тип такого члена данных является типом соответствующего захваченного объекта, если объект не является
ссылка на объект или ссылочный тип в противном случае.

Так, self копируется в закрытие на оценку (согласно §5.1.2 / 21):

Когда лямбда-выражение оценивается, объекты, захваченные копией, используются для прямой инициализации
каждый соответствующий элемент не статических данных результирующего объекта замыкания.

30

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]