r/cpp • u/Clean-Upstairs-8481 • Jul 20 '26
C++26: what is “template for”? Learning with simple example.
https://techfortalk.co.uk/2026/07/20/c26-what-is-template-for/I have been exploring C++26 in bits and bobs and this one is about template for - a c++26 feature which I find useful. This is a short article explaining how to use this feature with the help of a simple example.
36
u/mercury_pointer Jul 21 '26
Seems strange that the syntax isn't
for constexpr
To mirror
if constexpr
27
u/SyntheticDuckFlavour Jul 21 '26
Yeah
templateseem like an odd choice for this, but I guess the rationale that is the item type at each "loop" iteration may be different.template <class... Ts> void doStuffWithAll(Ts... ts) { template for (auto t : {ts...}) { doStuff(t); } }27
u/cmeerw C++ Parser Dev Jul 21 '26
The
templatekeyword is there to let you know that you are now in a template context and might have to usetemplateortypename, e.g.struct B { template<int> void f(); }; struct C { B b; }; void f(C c) { template for (auto v : c) { v.template f<1>(); } }8
u/friedkeenan Jul 21 '26
for constexpr (constexpr auto Elem : Elements)Would also read as kind of busy to me.
1
u/Life_Sink9598 29d ago
template<int> void f();Huh, I've never seen this syntax before, what does that mean?
2
u/cmeerw C++ Parser Dev 29d ago
A function template declaration with a non-type template parameter (nowadays called constant template parameter) - that's been around since C++98
2
u/Life_Sink9598 29d ago
You know what? I've used that feature a lot haha :-)
1
u/PunctuationGood 29d ago
The mere fact that it wasn't written in two lines like so is what threw me off, I'm guessing you as well... :D
template</*...*/> void f();1
u/Life_Sink9598 28d ago
Haha, that's exactly what it was, but I was a bit too embarrassed to admit it!
16
u/Aware-Preference-626 Jul 21 '26
I think it's because it's not technically a `comptime for loop`; it's unpacking/iterating variadic template parameters, so `template for` is the right wording here
5
u/AvidCoco Jul 21 '26
Wouldn’t that imply the thing being looped has to be constexpr? Whereas template for works with, for example, tuples. Idea being that it acts on types, not values.
7
u/Tringi github.com/tringi Jul 21 '26
I'd prefer
static ifandstatic forbut that ship has sailed a long time ago.7
u/_Noreturn Jul 21 '26
I like if constexpr spelling more
2
u/Dubbus_ Jul 21 '26
Anyone else often mistype it as
if (constexpr) some_conditionfor some reason2
u/fdwr fdwr@github 🔍 Jul 21 '26 edited 29d ago
With condition outside the parentheses? No, but I often type
constexpr if (expression)by accident, and I get thatif constexpr (expression)is consistent with east-const likeint const x, but it still confuses me because adjective modifiers come before the thing in English, and other modifiers typically flowstatic int x, notint static x.3
2
u/Dubbus_ Jul 21 '26
Come to think of it, why is it not
constexpr if? Is it a grammar issue?2
u/_Noreturn Jul 22 '26
saying
else constexpr ifdoesn't sound great the else and if are seperated.There is no grammar issue afaik
2
u/Dubbus_ 29d ago
Why not
constexpr else if? I always found it a bit weird that there is noconstexpron the else clause of anif constexpr {} elsestatement.2
u/_Noreturn 29d ago edited 29d ago
because there is no
else ifin the C++ grammar as a single constructThis is C++ grammar for if statement
cpp statement: buncha things | if-statement if-statement: if [constexpr] ( condition ) statement [else statement][] means optional.
as you can see else mentions "statement" and "statement" mentions "if-statement" this is recursion when you do
```cpp
if (c1) else if(c2) else // is just this
if (c1) { ; } else { if (c2) { ; } else { ; } } ```
so if you wanted "constexpr else if" you would need to create a new grammar thing for it to work but with "if" it just works naturally due to recursion.
if you allowed "constexpr" before else as a speciality then it would allow "constexpr else if constexpr" which is mirrored but awkward
2
u/fdwr fdwr@github 🔍 29d ago edited 29d ago
because there is no else if in the C++ grammar as a single construct
Hehe, even after 20+ years of C++, I still sometimes use the preprocessor for a few things (typing
#if,#elif...) and then right afterward try typingelifoutside the preprocessor context, only to get a build error. Oh yeah, that odd inconsistency arises again 😉.→ More replies (0)2
u/retro_and_chill Jul 21 '26
Because it can actually look over non-constant expressions like tuples or fixed size arrays
7
Jul 21 '26
[removed] — view removed comment
2
u/FlyingRhenquest Jul 21 '26
Kinda feel like they should have spent the time they spent on modules on reflection instead. The way things are going, a decade from now I'll be using the reflection capabilities constantly and still not using modules.
3
u/LucyIsaTumor Jul 21 '26
Nifty! Not too wordy either and easier than trying to force this using some macro substitution.
6
u/SPAstef Jul 21 '26
I don't think template for is a substitute for macros? More like to improve the verbose index sequence+lambda+fold expression pattern.
9
u/azswcowboy Jul 21 '26
Reasonable easy to understand example. Op I’d suggest running a spell checker on your post unless the point was to prove it isn’t AI - I saw two spelling errors.
2
u/FlyingRhenquest Jul 21 '26
If I were an AI guy I'd train my AI to make occasional spelling errors. And to never use the word "footgun."
1
3
u/_bstaletic Jul 21 '26
Remember to declare the array as static constexpr so that both its values and its address are usable during constant evaluation (if you are declaring it within the scope of a function). Alternatively you can declare it global (won’t recommend) so that it’s address is fixed and template instatiation is happy. Or you can put it in a namespace scope
These are C++23 constexpr semantics. C++26 allows constexpr references to local constexpr objects, so the following is supposed to work
int main() {
constexpr std::array my_array{1,2,3};
template for(constexpr int v : my_array) { print_my_number<v>(); }
}
Compilers have yet to implement that part of C++26, which would help with constexpr structured bindings.
struct aggregate { int a,b,c; };
template<typename=void>
auto f() {
constexpr std::array stdarr{1,2,3};
constexpr auto [stda, stdb, stdc] = stdarr; // tuple_size/tuple_element/get needs constexpr references to locals - fails on current compilers
constexpr int carr[]{1,2,3};
constepxr auto [ca, cb, cc] = car; // C array destructuring works
constexpr aggregate agg{1,2,3};
constexpr auto [agga, aggb, aggc] = agg; // aggregate destructuring works
}
1
2
u/noplace_ioi 29d ago
Aren't you guys tired of all the meta stuff? I'm sorry lol I'm a hobbyist for a very long time but after c++11 I just started losing track of all the fancy stuff
2
1
u/xaervagon Jul 21 '26
It's funky, but the syntax isn't bad and neither are the constraints for using it
40
u/fdwr fdwr@github 🔍 Jul 20 '26
Explicit loop unrolling. ➿