Захват ссылочной переменной путем копирования в C ++ 0x лямбда - PullRequest
32 голосов
/ 30 июня 2011

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

Использование следующего теста:

#include <stddef.h>
#include <iostream>

using std::cout;
using std::endl;

int main(int argc, char** argv)
{
    int i = 10;
    int& ir = i;

    [=]
    {
        cout << "value capture" << endl
             << "i: " << i << endl
             << "ir: " << ir << endl
             << "&i: " << &i << endl
             << "&ir: " << &ir << endl
             << endl;
    }();

    [&]
    {
        cout << "reference capture" << endl
             << "i: " << i << endl
             << "ir: " << ir << endl
             << "&i: " << &i << endl
             << "&ir: " << &ir << endl
             << endl;
    }();    

    return EXIT_SUCCESS;
}

Компиляция с GCC 4.5.1, использование -std=c++0x и запуск дают следующий вывод:

value capture
i: 10
ir: -226727748
&i: 0x7ffff27c68a0
&ir: 0x7ffff27c68a4

reference capture
i: 10
ir: 10
&i: 0x7ffff27c68bc
&ir: 0x7ffff27c68bc

При захвате копии ir просто ссылается на ненужные данные.Но он правильно ссылается на i при захвате по ссылке.

Это ошибка в GCC?Если так, кто-нибудь знает, исправляет ли это более поздняя версия?Каково правильное поведение?

РЕДАКТИРОВАТЬ

Если первая лямбда-функция изменяется на

[i, ir]
{
    cout << "explicit value capture" << endl
         << "i: " << i << endl
         << "ir: " << ir << endl
         << "&i: " << &i << endl
         << "&ir: " << &ir << endl
         << endl;
}();

, то вывод выглядит корректно:

explicit value capture
i: 10
ir: 10
&i: 0x7fff0a5b5790
&ir: 0x7fff0a5b5794

Это все больше и больше похоже на ошибку.

Ответы [ 2 ]

7 голосов
/ 05 июля 2011

Это было только что исправлено в стволе gcc-4.7 и ветке gcc-4.6. Они должны быть доступны в gcc-4.7.0 (некоторое время спустя - все еще на стадии 1) и gcc-4.6.2 (увы, только что вышла 4.6.1.)

Но intrepid может дождаться следующих снимков или получить копию subversion.

Подробнее см. контрольный журнал .

4 голосов
/ 30 июня 2011

Скомпилировано с VS 2010 дает:

value capture
i: 10
ir: 10
&i: 0012FE74
&ir: 0012FE78

reference capture
i: 10
ir: 10
&i: 0012FF60
&ir: 0012FF60

Похоже, ошибка для меня.

...