Может ли лямбда-выражение быть понижено до C++ 98
Недавно у меня возникла проблема с необходимостью интеграции кода C++ 11, написанного с лямбда-выражением, в старую базу кода, которая поддерживает только компилятор C++ 98. Я выяснил пару возможных эквивалентов лямбды, таких как макрос, функтор или указатель на функцию. Но, похоже, все они ограничены при переводе лямбды с захватом. Например, простая универсальная функция с обратным вызовом:
template <class Fn>
void ForEachObject(Fn fn)
{
for (uint i = 0; i < objectCount; i++)
{
fn(i, address + i * objectSize);
}
}
и типичный абонент будет делать что-то вроде:
uint attributes = 0x0030;
....
ForEachObject([=](uint index, void * objectAddress)
{
if ((ObjectInfo(index) & attributes) != 0)
{
fn(index, objectAddress);
}
});
Примечание атрибуты здесь выходят за рамки лямбды. Есть ли еще способ повторного использования для каждой логики без лямбды? Или я должен переписать логику на каждом таком звонящем?
2 ответа
С функтором:
struct Functor
{
explicit Functor(uint attributes) : attributes(attributes) {}
void operator () (uint index, void * objectAddress) const
{
if ((ObjectInfo(index) & attributes) != 0)
{
fn(index, objectAddress);
}
}
uint attributes;
};
А потом позвони
uint attributes = 0x0030;
// ....
ForEachObject(Functor(attributes));
Для каждой другой лямбды вы должны написать функтор. Вам не нужно изменять ForEachObject
Может ли выражение Lamda быть понижено до C++ 98
Нет, они не могут. Предыдущие стандарты C++11 не имеют понятия о лямбда-синтаксисе.
Хотя есть суррогаты, доступные как boost::lambda
Вы можете предоставить классы стиля функтора, переопределяя оператор вызова (<return_type> operator()(<args>);
), чтобы обеспечить такой же эффект, как указано в другом ответе.