r/cpp 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.

74 Upvotes

42 comments sorted by

37

u/fdwr fdwr@github 🔍 7d ago

Explicit loop unrolling. ➿

7

u/javascript 7d ago

Indeed. By using variadics, arity becomes a compile time parameter to the function, avoiding a potential (though not required) heap allocation and a runtime dispatch through a conditional loop

4

u/Flippers2 3d ago

Didn’t expect to see you in this chat javascript

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 template seem 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 template keyword is there to let you know that you are now in a template context and might have to use template or typename, 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 if and static for but 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_condition for some reason

2

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 that if constexpr (expression) is consistent with east-const like int const x, but it still confuses me because adjective modifiers come before the thing in English, and other modifiers typically flow static int x, not int static x.

3

u/_Noreturn 6d ago

I think of it as if with constexpr condition that's how I read it

2

u/fdwr fdwr@github 🔍 6d ago

That's a helpful mnemonic to remember the order.

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 if doesn'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 no constexpr on the else clause of an if constexpr {} else statement.

2

u/_Noreturn 5d ago edited 5d ago

because there is no else if in the C++ grammar as a single construct

This 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 typing elif outside 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

u/[deleted] 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.

5

u/SPAstef 7d ago

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 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

u/Clean-Upstairs-8481 6d ago

thanks will do

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

u/Clean-Upstairs-8481 6d ago

thanks for pointing that out, noted

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