cpp-ru / ideas

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

В С++20 добавить for constexpr вместо for... #385

Open Neargye opened 3 years ago

Neargye commented 3 years ago

Перенос предложения: голоса +23, -1 Автор идеи: Игорь Шаповал

В С++20 хотят добавить предложение expansion statements, которая подраздумевает добавление цикла foreach для работы во времени компиляции. Последняя редакция имеется p1306r1.

auto tup = std::make_tuple(0, ‘a’, 3.14);
for... (auto elem : tup) {
   std::cout << elem << std::endl;
}

Конструкция for... взята на подобии sizeof... . Но лучше сделать for constexpr на подобии к if constexpr.

В первой редакции p1306r0 предлагали два варианта: for... и for constexpr. В текущей редакции предлагается второй вариант писать следующим образом.

for... (constexpr meta::info member : members) {
   hash_append(h, t.idexpr(member));
}

Это не красиво и так и проситься написать вот так:

for constexpr (meta::info member : members) {
    hash_append(h, t.idexpr(member));
}

В предложении к статической рефлексии p0953r2 предлагается именно for constexpr.

Предлагаю добавить for constexpr как друга для if constexpr.

Neargye commented 3 years ago

Andrey Davydov 21 марта 2019, 13:08 1 Предлагается именно что expansion statement (тот случай когда название proposal'а действительно хорошо описывает его содержимое) а все expansion-ы в С++ делаются с помощью "...". Вы правы в том, что for... не похож на sizeof..., но это именно потому, что sizeof... выбивается из общего правила.

2 for (meta::info member : members) { ... }

Смотрите при итерации по массиву у нас есть 3 разных use case:

a) обычный runtime-цикл по массиву (используем обычный for),

б) мы хотим явно сделать loop-unrolling, так как размер массива известен в compile-time, естественно имеет смысл только для небольших массивов; в обеих версиях p1306 для этого предлагается использовать for...,

в) элементы массива это compile-time константы и мы хотим работать с ними как compile-time константами, для этого надо сделать во-первых loop-unrolling, во-вторых указать, что получаемый элемент constexpr, в p1306r0 как раз для этого использовался for constexpr, в p1306r1 справедливо решили что еще синтаксис для цикла for не нужен и можно использовать for... + constexpr на элементе for-а.

Игорь Шаповал 21 марта 2019, 22:46 Но в предложении к static reflection хотят сделать for constexpr а не for... Два синтаксиса вводить глупо.

А сделать один for constexpr будет классно.

Andrey Davydov 22 марта 2019, 11:56 Игорь Шаповал, какое именно предложение Вы имеете в виду? Дайте, пожалуйста, точную ссылку. Конечно, никому не хочется иметь 2 синтаксиса, но это, вроде и не требуется.

Игорь Шаповал 22 марта 2019, 18:26 static reflection http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2019/p0953r2.html

Andrey Davydov 22 марта 2019, 18:45 Игорь Шаповал, этот proposal не предлагает добавить constexpr for а ссылается как раз-таки на proposal Andrew Sutton'a так что проблемы с несогласованными for... и for constexpr нет.

Игорь Шаповал 22 марта 2019, 19:01 for constexpr как друг if constexpr очень выглядит красиво. Я думаю нужно быть последовательным. if constexpr - C++17, for constexpr - C++20.

Игорь Шаповал 3 апреля 2019, 8:52 yndx-antoshkka, скажите что нам ожидать - for...() или for constexpr() ?

apolukhin commented 3 years ago

Пока что люди в комитете склоняются к for ... https://wg21.link/p1717

Логика за выбором стоит следующая: фактически, такой цикл будет значить unroll, или раскрытие variadic pack, а это делается через многоточие. constexpr в if constexpr не меняет способ работы с внутренним выражением, оно всё ещё проверяет на true; в случае for это будет не так, и получится менее консистентно