#cpp #алгоритм #лямбда_выражение
Опишите пожалуйста плюси и минусы вариантов для конкретно этого примера(применение в std::for_each) , и когда и почему лямбда имеет преимущество(или наоборот) по отношению к функтору: ... void f(const int value) { cout << value << endl; } int main() { vectorv{1, 2, 3, 4, 5}; function op(&f) ; // функтор auto p = [](const int i) { return f(i + 5); }; // лямбда for_each(v.begin(), v.end(), op); // первый вариант for_each(v.begin(), v.end(), p); // второй вариант ... }
Ответы
Ответ 1
В качестве вишенки :) Создаю вектор и иже с ним: void f(int value) { sum += value; } const int Count = 100000000; vectorv(Count); generate(v.begin(),v.end(),g); function op(&f); Затем просто суммирую в глобальную переменную: for_each(v.begin(),v.end(),f); for_each(v.begin(),v.end(),[](const int i) { sum += i; }); for_each(v.begin(),v.end(),op); VC++2017 дал на моей машине следующие времена (в мс) - 187, 41 и 208 соответственно. Ideone дает примерно те же результаты. P.S. Явное создание struct Sum { void operator()(int value) { sum += value; } }; как и следовало ожидать, от лямбды ничем не отличается. Ответ 2
Ну, во-первых, в такой ситуации вы можете передавать в алгоритм прямо сразу f. Никакой оболочки вокруг f из лямбды или из std::function тут формально не требуется. (Разумеется, если вы хотите прибавить 5 к аргументу, то лямбда - именно то, что надо.) Во-вторых, при создании, удалении и на каждом вызове std::function тянет за собой накладные расходы, связанные с затратами на type erasure внутри std::function. Поэтому передавать std::function лучше только туда, где на входе требуется именно std::function. std::function предназначен в первую очередь для устранения зависимости принимающего алгоритма от шаблонного параметра, описывающего тип функтора. В вашем случае, т.е. для std::for_each, никакой речи о таком устранении не идет: в std::for_each тип функтора уже присутствует в списке шаблонных параметров, никто его не устранял и устранять не собирается. И поэтому платить накладные расходы за std::function нет никакого смысла. Лямбда тут будет работать эффективнее. Это относится ко всем стандартным алгоритмам: у них у всех типы функторов, предикатов, компараторов и т.п. вынесены в список параметров шаблона. В такой ситуации нет смысла использовать std::function без каких-то дополнительных/посторонних на то причин.
Комментариев нет:
Отправить комментарий