Означает ли [=], что все локальные переменные будут скопированы?

Когда я пишу лямбду с [=]Означает ли это, что все мои локальные переменные будут скопированы в члены созданной структуры, или я могу предположить, что только те, которые фактически используются в лямбда-выражении? Например:

void f()
{
vector<int> v(10000);
const int n = 5;
const int DivByNCnt = count_if(istream_iterator<int>(cin), istream_iterator<int>(),
[=](int i)
{
return i % n == 0;
});
}

Что из следующего, если таковое имеется, верно?

  • и n и v будут скопированы
  • n будет скопирован, v не будет
  • Будет скопировано n, v может или не может быть скопировано в зависимости от настроек имплементации / оптимизации.

Предположим, для аргумента, что конструктор копирования вектора имеет побочные эффекты.

61

Решение

Нет. Это просто означает, что все локальные переменные из окружения доступны для поиска в теле лямбды. Только если вы ссылаетесь на имя локальной переменной окружения, будет ли эта переменная захвачена, и она будет захвачена по значению.

Сокращения «захватить что-нибудь» = а также & это всего лишь синтаксический сахар, по сути, говорящий компилятору «понять, что я имею в виду».


Официальная ссылка от 5.1.2 / 11-12:

Если лямбда-выражение имеет связанный Захват по умолчанию И его компаунд-заявление odr-использует […] переменную с автоматической продолжительностью хранения, и объект, используемый в odr, не фиксируется явно, тогда объект, используемый в odr, называется неявно захваченный […]

Сущность захваченный если он захвачен явно или неявно.

Обратите внимание, что «Захват по умолчанию» относится к [=] а также [&], Повторим, что указание захвата по умолчанию ничего не захватывает; только переменная с использованием odr.

63

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

Нет! (К счастью)

Вы можете использовать свой код для проверки, действительно ли ваш компилятор делает это (или нет). Например gcc 4.8.0 кажется, соответствует.


Что касается того, что на самом деле предписывает Стандарт (работает в обратном направлении):

§5.1.2 / 14 Сущность захваченный копией если он неявно захвачен и захват по умолчанию = или если он явно захвачен с захватом, который не включает &, Для каждого объекта, захваченного копией, в типе замыкания объявляется неназванный нестатический элемент данных.

$ 5.1.2 / 11 Если лямбда-выражение имеет связанный захват-по умолчанию и его составной оператор odr-использует (3.2) this или переменная с автоматическим сроком хранения и объектом, используемым в odr, явно не фиксируется, тогда объект, используемый в odr, называется неявно захваченным; такие объекты должны быть объявлены в пределах охвата лямбда-выражения.

§5.1.2 / 9 Лямбда-выражение, наименьшая охватывающая область которого является областью блока (3.3.3), является локальным лямбда-выражением; любое другое лямбда-выражение не должно иметь список захвата в своем лямбда-представителе. достижение области локального лямбда-выражения — это набор окружающих областей вплоть до самой внутренней включающей функции и ее параметров. [Примечание: эта область охвата включает любые промежуточные лямбда-выражения. —Конечная записка]

22