C++11 лямбда-функции внутри методов-членов наследуют область видимости


Я написал функцию foreach, которая принимает лямбда-функцию ala:

void foreach(void (*p)(pNode))
{ /* ... */ }

Который работает как задумано, если я передаю лямбда-функцию из основного цикла:

int a = 5;
env.N().foreach
(
    [&](pNode n)->void
    {
        n->tps(a); 
    }
);

Однако, если я попытаюсь вызвать ту же функцию из метода-члена, лямбда-функция "наследует" область действия функции-члена и генерирует ошибку компилятора. Например, если я попытаюсь включить его в метод-член класса Object с именем method(), я получу следующую ошибку:

error: no matching function for call to ‘IDSet<Node>::foreach(Object::method()::<lambda(pNode)>)’
note: candidate is: void IDSet<T>::foreach(void (*)(IDSet<T>::pT)) [with T = Node, IDSet<T>::pT = pNode]

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

Я пробовал reinterpret_cast, однако это дает мне эту ошибку:

error: invalid cast from type ‘Object::method()::<lambda(pNode)>’ to type ‘void (*)(pNode)’

Указание static перед [&](pNode ... также не похоже на допустимый синтаксис.

Отчаянно, я также попытался изменить [&] на [=], [], [a], ничего из этого работал.

Кто-нибудь знает, есть ли способ выполнить мою цель создания "статической" лямбда-функции или любой другой лямбда-функции, которая будет принята в этом отношении?

Спасибо!


Ответ:

С помощью Cat Plus Plus я смог включить свой неверный код:

void foreach(void (*p)(pT))
{
    for(pTiter i = _map.begin(); i != _map.end(); i++)
    {
        (*p)(i->second);
    }
}

В полнофункциональный код:

void foreach(std::function<void(pT)>(p))
{
    for(pTiter i = _map.begin(); i != _map.end(); i++)
    {
        p(i->second);
    }
}

, что делает то, что я искал, совершенно.

1 7

1 ответ:

Ну, вы не можете использовать указатели.

void foreach(std::function<void(pNode)>);