Почему переменная-член класса не может быть [&A, &B] в PPL

Перед компиляцией VS говорит, что

Ошибка участника test::A не является переменной

Ошибка члена test::B не является переменной

Код:

#include <iostream>
#include <ppl.h>

using namespace concurrency;
using namespace std;

class test
{
        static double A[ 3 ][ 3 ];
        static double B[ 3 ][ 3 ];
public:
        int test_function();
};

double test::A[ 3 ][ 3 ] = { {  0.7,  -0.2,   -1   },
                             { -4,    -2,     -2   },
                             { -0.4,   1.7,   -1.8 } };

double test::B[ 3 ][ 3 ] = { {  0.6,  -1.2,    1.1 },
                             {  2,     3,     -2   },
                             { -1,     0.05,   0.05} };

int test::test_function()
{
    parallel_for ( 0, 100, [ &A, &B ]( int y ) {
        for ( int x = 0; x < 100; x++ ) {

            for ( int i = 0; i < 3; i++ )
                for ( int j = 0; j < 3; j++ )
                     A[ j ][ i ] += A[ j ][ i ] * B[ j ][ i ];

        }
    } );
}

int main()
{
        return 0;
}

Ошибка:

'test::A': переменная захвата лямбда должна быть из объемлющей функции.

'test::B': переменная захвата лямбда должна быть из объемлющей функции.

что я должен делать?


person user2055437    schedule 13.02.2013    source источник
comment
Работает без захватов? Вам не нужно снимать статику.   -  person Pubby    schedule 13.02.2013
comment
Зачем вам захватывать статические переменные?   -  person Bo Persson    schedule 13.02.2013
comment
Я новичок в С++, как мне обойтись без захватов? Можете ли вы привести пример?   -  person user2055437    schedule 13.02.2013
comment
Просто измените [ &A, &B ] на [].   -  person Pubby    schedule 13.02.2013
comment
я меняю код, я должен защитить A и B, потому что общий элемент   -  person user2055437    schedule 13.02.2013


Ответы (1)


Захват статических данных не имеет смысла, поскольку они являются статическими для класса. Лямбда, определенная внутри функции, имеет такую ​​же доступность, как и функция, в которой она определена. Таким образом, переменные, видимые внутри этой функции (например, приватные классы), видны и в лямбда-выражении.

Статические члены класса все равно будут существовать, даже если функция будет передана в другом месте или переживет текущую область.

Так что просто используйте [] в своей лямбде вместо [ <stuff> ].

person Nicol Bolas    schedule 13.02.2013
comment
За исключением того, что они являются частными глобальными. У них еще есть доступ? - person Pubby; 13.02.2013
comment
@Pubby: Извини; пропустил это. Но логика остается прежней. И да, у них есть доступ; лямбда от члена класса считается членом класса. - person Nicol Bolas; 13.02.2013
comment
как можно защитить A, это глобальный и общий элемент? - person user2055437; 13.02.2013
comment
@ user2055437: От чего вам нужно его защитить? Частные переменные доступны внутри членов (и друзей). Ваша лямбда фактически является членом по доверенности, поскольку она может обращаться к закрытым переменным. Не говоря уже о том, что лямбда определена в том же месте, что и функция-член, поэтому любой, кто может внедрить некоторый код в лямбда-выражение, может внедрить некоторый код в функцию-член. Не от чего защищать A. - person Nicol Bolas; 13.02.2013
comment
я неправильно спросил, не защитить, скажем, заблокировал их, потому что в процессе результат массива отличается - person user2055437; 13.02.2013
comment
@ user2055437: Если вы говорите о мьютексах и условиях гонки, то это совершенно другой вопрос. Вы должны задать это с помощью кнопки «Задать вопрос»; этот текущий вопрос касается лямбда-выражений. Кроме того, неясно, что должен делать этот цикл parallel_for, поскольку каждая итерация будет вычислять одно и то же. - person Nicol Bolas; 13.02.2013