🇺🇦 Про айті та дотичні теми загалом, ну й трохи про C++.
Усі думки тут відображають виключно мій особистий погляд.
Мої емоджі:
https://t.me/addemoji/AdaptiveDevIcons
https://t.me/addemoji/VehicleBrands
Post #502
885
Думав написати про це ще минулої середи, але ви мені тоді точно не повірили би 😄
Отже, в C++ тепер є новий різновид циклів —
Раніше довелось би писати щось отаке:
Ніби й зрозуміло, що
Тобто типовий ФП-підхід, де список ділиться на
А тепер можна буде писати отак:
Усе це розгортається під час компіляції в щось на кшталт:
Працює
перетворюється на
Ну й ще багато чого можна робити звісно. Проте найкраще ця штука себе показує з новою рефлексією, про котру ще згодом напишу.
Отже, в C++ тепер є новий різновид циклів —
template for 🙂 Хочемо, ми, наприклад, написати функцію зі змінною кількістю аргументів, яка виводитиме значення в консоль:template <typename... Ts> void print_all(Ts... elems);
print_all("foo", 42, 'p', 3.14); // використання
Раніше довелось би писати щось отаке:
template <typename... Ts>
void print_all(Ts... elems)
{
(std::println("{}", elems), ...);
}
Ніби й зрозуміло, що
elems розпаковуються в пачку виразів, кожний з яких — це println, але читається не дуже. Тому знавці використовували би, мабуть, 🐝 Boost.Hana. А в C++11 взагалі колись писали отак:void print_all() {}
template <typename T, typename... Ts>
void print_all(T first, Ts... rest) {
std::cout << first << std::endl;
print_all(rest...);
}Тобто типовий ФП-підхід, де список ділиться на
head:[tail] й обходиться рекурсивно, доки не дійде до порожнього.А тепер можна буде писати отак:
template <typename... Ts>
void print_all(Ts... elems) {
template for (auto elem : {elems...}) {
std::println("{}", elem);
}
}
Усе це розгортається під час компіляції в щось на кшталт:
template <typename... Ts>
void print_all(Ts... elems) {
{
{
auto elem = elems...[0]; // така індексація,
// до речі, також
// нова фіча
std::println("{}", elem);
}
{
auto elem = elems...[1];
std::println("{}", elem);
}
{
auto elem = elems...[2];
std::println("{}", elem);
}
}
}
Працює
template for не лише з пачками типів, але й з будь-чим. Наприклад, звичайними масивами. Такvoid f() {
template for (constexpr int I : std::array{1, 2, 3}) {
static_assert(I < 4);
}
}перетворюється на
void f() {
{
constexpr auto&& __range = std::array{1, 2, 3};
constexpr auto __begin = __range.begin();
constexpr auto __expansion_size = __range.end() - __begin; // 3
{
constexpr int I = *(__begin + 0);
static_assert(I < 4);
}
{
constexpr int I = *(__begin + 1);
static_assert(I < 4);
}
{
constexpr int I = *(__begin + 2);
static_assert(I < 4);
}
}
}Ну й ще багато чого можна робити звісно. Проте найкраще ця штука себе показує з новою рефлексією, про котру ще згодом напишу.
- ❤🔥 7
- 👍 5
- 🤯 2
- 🔥 1
- 🤔 1
- 🤣 1









