Инициализация массивов и контейнеров лямбдой (compile-time)

Denis
Denis

В C++17 мы уже можем инициализировать массив не тривиальным образом во время компиляции, но для этого нам нужно писать constexpr функцию, например:

#include <array>

constexpr std::array<int, 9> init() {
    std::array<int, 9> arr {};

    for(int i = 0; i < arr.size(); i++) {
        arr[i] = i * i;
    }

    return arr;
} 

int main() {

    std::array<int, 9> arr = init();

    return arr[3];
}

Как вариант, можно было бы использовать подобный синтаксис (как будто встроенный std::generate):

#include <array>

int main() {

    std::array<int, 9> arr{(v.begin(), v.end(), [n = 0] () mutable { return n++; })};

    return arr[3];
}
3
рейтинг
2 комментария
yndx-antoshkka

Кажется можно уже сейчас нечто подобное получить с ranges (код не проверял):

auto arr = ranges::view::iota(0, 9) | ranges::to<std::array<int, 9>>;

Но написать функцию - намного читаемее, чем два предложеных подхода.

yndx-antoshkka
Denis

yndx-antoshkka, спасибо за наводку.
Действительно, с помощью ranges похоже можно делать то, что хотел, правда не понятно, будет ли возможность делать это compile-time в C++20

Denis
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения