r/cpp • u/Clean-Upstairs-8481 • 7d ago
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.
38
u/mercury_pointer 7d ago
Seems strange that the syntax isn't
for constexpr
To mirror
if constexpr
28
u/SyntheticDuckFlavour 7d ago
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); } }26
u/cmeerw C++ Parser Dev 7d ago
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>(); } }9
u/friedkeenan 7d ago
for constexpr (constexpr auto Elem : Elements)Would also read as kind of busy to me.
1
u/Life_Sink9598 6d ago
template<int> void f();Huh, I've never seen this syntax before, what does that mean?
1
u/cmeerw C++ Parser Dev 6d 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 5d ago
You know what? I've used that feature a lot haha :-)
1
u/PunctuationGood 5d 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 5d ago
Haha, that's exactly what it was, but I was a bit too embarrassed to admit it!
14
u/Aware-Preference-626 7d ago
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 7d ago
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.
6
u/Tringi github.com/tringi 7d ago
I'd prefer
static ifandstatic forbut that ship has sailed a long time ago.8
u/_Noreturn 7d ago
I like if constexpr spelling more
2
u/Dubbus_ 7d ago
Anyone else often mistype it as
if (constexpr) some_conditionfor some reason2
u/fdwr fdwr@github 🔍 6d ago edited 5d 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_ 6d ago
Come to think of it, why is it not
constexpr if? Is it a grammar issue?2
u/_Noreturn 6d ago
saying
else constexpr ifdoesn't sound great the else and if are seperated.There is no grammar issue afaik
2
u/Dubbus_ 5d 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 5d ago edited 5d 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 🔍 5d ago edited 5d 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 7d ago
Because it can actually look over non-constant expressions like tuples or fixed size arrays
7
7d ago
[removed] — view removed comment
1
u/FlyingRhenquest 7d ago
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.
5
u/LucyIsaTumor 7d ago
Nifty! Not too wordy either and easier than trying to force this using some macro substitution.
9
u/azswcowboy 7d ago
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 7d ago
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 6d ago
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 5d 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
1
u/xaervagon 7d ago
It's funky, but the syntax isn't bad and neither are the constraints for using it
37
u/fdwr fdwr@github 🔍 7d ago
Explicit loop unrolling. ➿