From c7a61da1504c69ad42b9a8344d78fc5684d19fc4 Mon Sep 17 00:00:00 2001 From: Matthias Wippich Date: Mon, 9 Mar 2026 22:28:15 +0100 Subject: [PATCH 1/2] Improve P1789 description Signed-off-by: Matthias Wippich --- .../expansion-statements-library-support.md | 69 ++++++++++++++----- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/content/expansion-statements-library-support.md b/content/expansion-statements-library-support.md index b9233b1..698d518 100644 --- a/content/expansion-statements-library-support.md +++ b/content/expansion-statements-library-support.md @@ -4,37 +4,70 @@ execute: true ## What It Does -`std::integer_sequence` can now be used in `template for` -to conveniently write a loop where the loop index is a `constexpr` variable, -as well as to create a `constexpr` pack using structured bindings. -This is made possible by specializing `std::tuple_size`, `std::tuple_element`, and `std::get` -for `std::integer_sequence`. +`std::integer_sequence` can now be used in `template for` to conveniently write a loop +where the loop index is a `constexpr` variable. Additionally it can be used to create a +`constexpr` pack in the current function scope through structured bindings. + +This is made possible by implementing the tuple protocol for `std::integer_sequence` ( +specializing `std::tuple_size` + `std::tuple_element` and providing overloads for `get`). ## Why It Matters -These changes remove boilerplate code such as creating an immediately invoked lambda expression -when creating a `constexpr` pack of indices or writing a loop with a `constexpr` index. -This is especially important because C++26 supports pack indexing, -where a `constexpr` index is needed. +These changes obsolete the common metaprogramming idiom of using an immediately invoked lambda +expression to introduce a pack of constant indices. This is especially interesting when operating +on multiple packs (or tuple-likes) of equal size at the same time. + +This change has intended symbiotic effects with +- P1306 expansion statements (`template for`) +- P2662 pack indexing (`Pack...[Idx]`) +- P1061 structured bindings can introduce a pack + P2686 constexpr structured bindings +- P3096 function parameter reflection (IILE trick cannot be used here) + ## Example ```cpp +#include #include #include -#include + + +// before C++26 +template +bool is_eq_iile(std::tuple lhs, std::tuple rhs) { + return [&](std::index_sequence) { + return ((get(lhs) == get(rhs)) && ...); + }(std::index_sequence_for()); +} + +// with structured bindings +template +bool is_eq_fold(std::tuple lhs, std::tuple rhs) { + static constexpr auto [...Idx] = std::index_sequence_for(); + return ((get(lhs) == get(rhs)) && ...); +} + +// with expansion statements +template +bool is_eq_template_for(std::tuple lhs, std::tuple rhs) { + template for (constexpr auto Idx : std::index_sequence_for()) { + if (get(lhs) != get(rhs)) { + return false; + } + } + return true; +} int main() { auto tup = std::tuple{1, 3.14, "hello"}; + auto tup2 = std::tuple{2, 3.14, "hell"}; - // Output: - // tup[0] = 1 - // tup[1] = 3.14 - // tup[2] = hello - template for (constexpr std::size_t I : std::make_index_sequence<3>()) { - std::println("tup[{}] = {}", I, std::get(tup)); - } + assert(not is_eq_iile(tup, tup2)); + assert(not is_eq_fold(tup, tup2)); + assert(not is_eq_template_for(tup, tup2)); - constexpr auto [...Is] = std::make_index_sequence<3>(); + assert(is_eq_iile(tup, tup)); + assert(is_eq_fold(tup, tup)); + assert(is_eq_template_for(tup, tup)); } ``` From 84735014e3e179f7f689902fd0b034dd3a3cc647 Mon Sep 17 00:00:00 2001 From: Matthias Wippich Date: Tue, 10 Mar 2026 00:52:29 +0100 Subject: [PATCH 2/2] Update expansion-statements-library-support.md Signed-off-by: Matthias Wippich --- content/expansion-statements-library-support.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/expansion-statements-library-support.md b/content/expansion-statements-library-support.md index 698d518..7fbfb50 100644 --- a/content/expansion-statements-library-support.md +++ b/content/expansion-statements-library-support.md @@ -62,9 +62,9 @@ int main() { auto tup = std::tuple{1, 3.14, "hello"}; auto tup2 = std::tuple{2, 3.14, "hell"}; - assert(not is_eq_iile(tup, tup2)); - assert(not is_eq_fold(tup, tup2)); - assert(not is_eq_template_for(tup, tup2)); + assert(!is_eq_iile(tup, tup2)); + assert(!is_eq_fold(tup, tup2)); + assert(!is_eq_template_for(tup, tup2)); assert(is_eq_iile(tup, tup)); assert(is_eq_fold(tup, tup));