инициализация вектора с использованием лямбда-индекса в c ++ - PullRequest
2 голосов
/ 27 апреля 2020

Существует ли библиотечная функция для инициализации вектора на основе индекса его элементов?

Это сократило бы такие вещи, как:

#include <vector>

using namespace std;
int main() {
  auto square = [] (int n) {return n*n;};

  vector<int> v(5, 0);
  for (int i = 0; i < 5; i++){
    v[i] = square(i);
  }
}

Ответы [ 2 ]

3 голосов
/ 27 апреля 2020

Путь, который приходит на ум, состоит в том, чтобы разбить его на два этапа. В этом случае std::iota заполнит вектор входами (0, 1, 2 и т. Д. c). Затем std::transform выполнит вашу функцию square для каждого из элементов и заменит их в векторе.

int main()
{
    auto square = [] (int n) {return n*n;};

    std::vector<int> v(5, 0);
    std::iota(v.begin(), v.end(), 0);
    std::transform(v.begin(), v.end(), v.begin(), square);

    for (int i : v)
      std::cout << i << ' ';
}

Выход

0 1 4 9 16  

Честно говоря, такие вещи будут намного более краткими и упрощенными, как только диапазоны доступны, C ++ 20 рабочий пример

int main()
{
    auto square = [] (int n) {return n*n;};

    for (int i : std::views::iota(0, 5) | std::views::transform(square))
        std::cout << i << ' ';
}
2 голосов
/ 27 апреля 2020

Для вектора есть простой способ вычислить его индекс путем вычитания указателей:

std::for_each(v.begin(),v.end(), 
    [&v,&square](auto& elem){ elem = square(&elem - &v[0]);});

на auto& elem вы получаете доступ к исходному элементу вектора, тогда индекс вычисляется как &elem - &v[0], который передается в square.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...