cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

for constexpr #141

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +36, -0 Aвтор идеи: Сергей Тиунов

Мотивация

Бывают ситуации, когда было бы удобно организовать код в виде простого цикла (с известными пределами), но это сделать невозможно, потому что счетчик должен быть compile-time константой, например, он используется в виде параметра шаблона:

for (int i = 0; i < 3; i++) {
  some_template_function<i>(); // compilation error: 
  // variable with non-static storage duration cannot be used as a non-type argument
}

Примеры, когда нужно или желательно, чтобы счетчик цикла был compile-time константой:

Для того чтобы добиться подобного поведения в текущей версии С++, можно:

Предложение

Вместо этого предлагается цикл с семантикой явного разворачивания: т.е. он записывается как цикл, но все управляющие конструкции (init statement, condition, iteration expression) вычисляются в compile-time. Тогда их можно использовать в качестве compile-time констант в constexpr выражениях, if-constexpr условиях, параметрах шаблонов и подобных контекстах. По аналогии с if-constexpr это могло бы выглядеть так:

for constexpr (int i = 0; i < 3; i++) {
  some_template_function<i>(); // i is constexpr - okay, should compile
}

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

some_template_function<0>();
some_template_function<1>();
some_template_function<2>();

... однако в отличие от него не содержит дублирования кода.

apolukhin commented 3 years ago

Сергей Вахреев, 13 марта 2017, 13:14 Вроде for constexpr хотят внедрить для итерации по variadic templates... Было бы почти красиво, если бы лямбды поддерживали template параметры: https://godbolt.org/g/yojZLK Тогда можно было бы использовать if constexpr и другие compile time фичи. Хотя при -О3 компилятор идёт внутрь лямбд и оптимизирует код так же, как и при constexpr if в подобной реализации: https://godbolt.org/g/RSXOe8

Никто не подскажет, что с этим proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0428r0.pdf ?

Сергей Вахреев, 13 марта 2017, 13:40 С расширением templated lambdas от gcc: https://godbolt.org/g/sKvMQS (по вышеприведенному proposal) Выбираемый диапазон индексов можно сделать по подобию boost::hana

Михаил Мальцев, 13 марта 2017, 20:28 Сергей Вахреев,

Никто не подскажет, что с этим proposal

В Иссакуа его одобрили в EWG. В Коне у CWG возникла пара замечаний, которые предстоит исправить.

Игорь, 21 марта 2017, 14:33 Сергей Вахреев, лямбды всё уже поддерживают, в чём у вас проблема? http://melpon.org/wandbox/permlink/jGbRr6PnePbZQAhz

Игорь, 21 марта 2017, 14:37 Михаил Мальцев, печально, что одобрили. Мало зубодробительного контекстно-зависимой грамматики - давайте ещё усложним и накрутим лямбды :( Воистину, каждый, предлагающий изменение в C++, для начала должен пожертвовать почку.

Сергей Вахреев, 21 марта 2017, 15:45 Игорь, у меня никаких проблем нет. Просто не додумался / потратил мало времени на эксперименты / не знал. Выберите понравившийся вариант сами.

Михаил Мальцев, 13 марта 2017, 20:22 Уже есть аналогичное предложение "Tuple-based for loops": http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0589r0.pdf

Сергей Тиунов, 19 июня 2017, 19:15 Михаил Мальцев, согласен, предложение аналогичное в том плане, что варианты взаимозаменяемы:

auto indices = std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
for (auto i : indices) { ... }

constexpr int size = std::tuple_size<decltype(tup)>::value;
for constexpr (int i = 0; i < size; i++) { auto elem = std::get<i>(tup); ... }

Однако мне кажется, что for constexpr в большинстве практических приложений будет удобнее, тогда как tuple-based for loop мне кажется удобным только вместе с рефлексией (например, напечатать все поля структуры).

apolukhin commented 3 years ago

Подгруппа SG7: Reflection занята проработкой этой идеию Синтаксис у них несколько отличатеся for... https://wg21.link/p1717r0