Как получить доступ к локальным переменным из анонимной функции С++ 11?

Я делаю простую нормализацию по вектору (весам), пытаясь использовать алгоритмы STL, чтобы сделать код максимально чистым (я понимаю, что это довольно тривиально для циклов):

float tot = std::accumulate(weights.begin(), weights.end(), 0.0);
std::transform(weights.begin(), weights.end(), [](float x)->float{return(x/tot);});

В настоящее время функция tot не отображается анонимной функции, поэтому она не компилируется. Какой лучший способ сделать локальную переменную видимой для анонимной функции?

Ответ 1

Вам нужно закрыть.

float tot = std::accumulate(weights.begin(), weights.end(), 0);
std::transform(weights.begin(), weights.end(), [tot](float x)->float{return(x/tot);});

В этом случае tot фиксируется по значению. С++ 11 поддержка lambdas:

  1. значение [x]
  2. ссылка [&x]
  3. любая переменная, находящаяся в настоящее время в области по ссылке [&]
  4. то же, что и 3, но по значению [=]

Вы можете смешать все вышеперечисленное в списке, разделенном запятыми [x, &y].

Ответ 2

Лямбда может "захватывать" переменные из окружающего пространства:

[ ..., N, ... ](int a, int b) -> int  { return (a + b) * N; }
 ^^^^^^^^^^^^^  ^^^^^^^^^^^^     ^^^^
 captured vars  local params     ret.type

Вы можете захватывать по значению или по ссылке, и вы можете использовать специальный синтаксис [=] и [&] для захвата чего-либо из области видимости, то есть всего, что вы на самом деле используете.

Ответ 3

Вам нужно добавить tot в "список захвата":

float tot = std::accumulate(weights.begin(), weights.end(), 0);
std::transform(weights.begin(), weights.end(), [tot](float x)->float{return(x/tot);});

В качестве альтернативы вы можете использовать захват-по умолчанию, чтобы фиксировать tot неявно:

float tot = std::accumulate(weights.begin(), weights.end(), 0);
std::transform(weights.begin(), weights.end(), [=](float x)->float{return(x/tot);});