Как стать автором
Обновить

Комментарии 20

Поскольку речь идёт о современном C++, есть смысл использовать std::array<T, N>. Compile-time размер, тип, всё сразу без дополнительных хаков.


Например, ваш forEachOnAnArray преобразуется в:


template<typename T, std::size_t N, typename F>
void forEachOnAnArray(std::array<T, N> &arr, F &callback) {
  for (auto& el: arr)
   callback(el);
};
Спасибо за коммент!

Я понимаю о чем Вы говорите, но почему-то Скотт пишет об этих возможностях. Я, в свою очередь, от себя я добавил лишь пару примеров, которые не о std::array, а о выведении типа для классического массива. Кому-то это может оказаться интересным и полезным.

Простой вопрос: зачем писать про выведение типа? Все функции, которые выполнял C-style массив, сейчас выполняются std::array. Плюс, он дружелюбнее к алгоритмам, т.к. предоставляет все необходимые итераторы.


Ну и да, у вас тут из современного C++ только лямбда в последнем листинге.

Простой ответ: для понимания неочевидных вещей.
Для количества измерений массива больше одного, си-шная нотация массива иногда удобней. А с++ правильно определяет константные размерности в темплете и генерирует очень эффективный код. В том числе и без стдлиб
Можно поинтересоваться, что дают итераторы алгоритмам? Я не против std::array, сам его и использую, если что) Просто любопытно. С алгоритмами std и им подобными можно ведь и обычный С-массив юзать. Там так же и размер последовательности узнаем, и тип значения (вместо InputIt::value_type, используем decltype(*it)). Что еще требуют алгоритмы от итераторов? P. S. Напоминаю, что мне просто любопытно)

Лично мне куда больше нравится запись в плюсовом стиле, чем в C:


// cpp
std::array<int, 10> arr;
std::sort(arr.begin(), arr.end());

// plain C
arr[10];
std::sort(arr, arr + 10);

Итераторы не дают ничего кардинально нового, но, например, с "голыми" указателями сложнее идти по массиву в обратную сторону, в STL для этого есть reverse_iterator. Например, rotate вправо, который на порядок сложнее сделать только на указателях:


std::rotate(arr.rbegin(), arr.rbegin() + 1, arr.rend());

От себя добавлю, что, всё же, в вашем примере, plain C-версия тоже может быть аккуратненькой:


arr[10];
std::sort(std::begin(arr), std::end(arr));

До 17х плюсов, единственный момент, где удобно использовать C-шные массивы — так это при объявлении "константных массивов", когда можно просто добавлять элементы в конец и не париться про размер, например:


const struct
{
    const int id;
    const char* const name;
} k_info[]
{
    {1, "id1"},
    {2, "id1"},
    {3, "id1"},
    {4, "id1"},
};

Позже, чтобы добавить новый элемент в такой массив, я просто иду и добавляю строчку в конец, не меняя в другом месте (пару строчек выше) размер массива в случае с std::array + с ним не получится использовать анонимную структуру. Но это мелочи.


После 17тых плюсов, использовать std::array для таких случаев стало немного удобней:


std::array data = {1, 2, 3, 4};

работает на ура благодаря class template argument deduction

Все же самая удобная вещь, которая есть у std::array — value-семантика, т.е. возможность возвращать массив в качестве результата работы функции, что очень constexpr-friendly


P.S. Пардон, промахнулся со стрелкой, компенсировал в карму. :)

В Visual studio не работает. :(
В Visual Studio 2017 по умолчанию установлен /std:c++14. Поменяйте на /std:c++17 или /std:c++latest

Не помогло. С какой версии студии поддерживается эта фича?

15.7, когда они заявили о полной поддержке C++17
Обновил студию с 15.7.3 до 15.7.4 (версия cl.exе стала 19.14.26431.0). Теперь код компилируется, но InteliSense все равно подчеркивает ошибку, требуя аргументы шаблона.
Странно, у меня 15.7.0 (19.14.26428.1) и всё в порядке
InteliSense тоже нормально работает?
Да, корректно отрабатывает
Откройте для себя make_reverse_iterator, а лучше std::rbegin/rend.

rextester.com/FHC89361
У Вас в примере №1 в коде написано «N <= 121», а тексте ошибки внизу — «N <= 120», так вроде не должно быть.
Спасибо, picul, исправил…
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории