допустимый захват переменной из лямбды - PullRequest
3 голосов
/ 19 октября 2011

Мне интересно, допустим ли следующий стиль захвата по ссылке:

struct Foo {
 Foo( boost::function<void()> v);

 int get() const;
};

int main() {
 Foo instance( [&]() -> void { int value = instance.get(); .... } );

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

Ответы [ 2 ]

2 голосов
/ 19 октября 2011

Лямбда не выполняется, пока вы не выполните ее, написав v() в конструкторе Foo.И если вы это сделаете, то это будет так же, как если бы вы вызывали функцию get() непосредственно из конструктора, что нормально, , если get не является функцией virtual, и вы реализовали get таким образом, чтобы его также можно было вызывать из конструктора.Например, если вы сделаете это:

В этом случае реализация get не требует, чтобы объектбыть полностью построенным.

Кроме того, хотя это не связано с вашим вопросом, но все же обратите внимание, что, поскольку вы используете C ++ 11 (как подразумевается при использовании лямбды), почему бы вам неиспользовать std::function вместо boost::function (как я делал в своей демоверсии )?Если ваш компилятор поддерживает лямбду, он также будет поддерживать std::function, поскольку его реализация очень тривиальна.

1 голос
/ 19 октября 2011

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

...