Замена функции лямбда-выражением в C ++ - PullRequest
0 голосов
/ 20 марта 2019

У меня есть функция, которая просто устанавливает значение 1 для переменной члена структуры length.В современном C ++ это не похоже на хороший стиль кода.Можно ли это сделать с помощью лямбды?

void setEdgeLengths(Koala::AssocArray <koalaGraph::PEdge, Koala::DijkstraHeap::EdgeLabs<int >> &edgeMap, std::vector<koalaGraph::PEdge>& E) 
{
    for (size_t i = 0; i < E.size(); i++) {
    edgeMap[E[i]].length = 1;
    }
}

Причина, по которой я спрашиваю: https://shaharmike.com/cpp/lambdas-and-functions/ предполагает, что лямбда будет работать быстрее, чем обычная функция.

Лямбды также хороши, когда дело доходит доспектакль.Поскольку они являются объектами, а не указателями, они могут быть очень легко вставлены компилятором, как функторы.Это означает, что многократный вызов лямбды (например, с помощью std :: sort или std :: copy_if) намного лучше, чем использование глобальной функции.Это один пример того, где C ++ на самом деле быстрее, чем C.

Ответы [ 2 ]

3 голосов
/ 20 марта 2019

Я бы посчитал следующий код оптимальным (помимо заданных имен переменных):

void setEdgeLengths(Koala::AssocArray <koalaGraph::PEdge, Koala::DijkstraHeap::EdgeLabs<int >> &edgeMap, std::vector<koalaGraph::PEdge>& E) 
{
    for (const auto& e : E) {
        edgeMap[e].length = 1;
    }
}

Стиль (или опускание) фигурных скобок, как вам нравится.

Вы можете поставить любой иливсе это в произвольном количестве вложенных лямбд, но это не более полезно (но, вероятно, более вредно, по крайней мере, в отладочных сборках), чем добавление большего количества пробелов.Вероятно, вы хотели спросить следующее:

void setEdgeLengths(Koala::AssocArray <koalaGraph::PEdge, Koala::DijkstraHeap::EdgeLabs<int >> &edgeMap, std::vector<koalaGraph::PEdge>& E) 
{
    std::for_each(E.begin(), E.end(), [&edgeMap](const auto& e) {
        edgeMap[e].length = 1;
    });
}

У вас больше нет простого цикла (что некоторые считают хорошим стилем), но я не думаю, что код стал более понятным.Это также не ускорило выполнение этого - во всяком случае, производительность отладки, вероятно, немного снизилась.

Теперь последняя форма делает допускающей параллельное выполнение, выполняя

std::for_each(std::execution::parallel, E.begin(), E.end(), [&edgeMap](const auto& e) {

но это допустимо только в том случае, если ваш edgeMap правильно обрабатывает одновременный доступ.Если бы это был std::map, operator[] потенциально мог бы вставить новый элемент (который не является потокобезопасным), поэтому без дополнительных предположений это не было бы юридической оптимизацией.

1 голос
/ 20 марта 2019

Если вы хотите применить операцию к каждому элементу контейнера, вы можете использовать std::for_each.Поскольку вы хотите использовать каждый элемент E для доступа к edgeMap, вы будете использовать for_each на E, как

Koala::AssocArray <koalaGraph::PEdge, Koala::DijkstraHeap::EdgeLabs<int >> edgeMap = /* stuff */;
std::vector<koalaGraph::PEdge> E = /* stuff */;

std::for_each(E.begin(), E.end(),[&](auto const& index){ edgeMap[index].length = 1; });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...