Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

constexpr in for-Statement

c++17 provides if constexpr, in which:

the value of condition must be a contextually converted constant expression of type bool. If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded

Is there a way to use this in a for-statement as well? To unroll a loop at compile time? Id like to be able to do something like this:

template <int T>
void foo() {
   for constexpr (auto i = 0; i < T; ++i) cout << i << endl;
}
like image 598
Jonathan Mee Avatar asked Feb 21 '18 18:02

Jonathan Mee


2 Answers

Is there a way to use this in a for-statement as well? To unroll a loop at compile time? Id like to be able to do something like this

I don't think in a so simple way.

But if you can afford an helper function, with std::integer_sequence and the initialization of an unused C-style array of integers, starting from C++14 you can do something as follows

#include <utility>
#include <iostream>

template <int ... Is>
void foo_helper (std::integer_sequence<int, Is...> const &)
 {
   using unused = int[];

   (void)unused { 0, (std::cout << Is << std::endl, 0)... };
 }

template <int T>
void foo ()
 { foo_helper(std::make_integer_sequence<int, T>{}); }

int main ()
 {
   foo<42>();
 }

If you can use C++17, you can avoid the unused array and, using folding, foo_helper() can be simply written as follows

template <int ... Is>
void foo_helper (std::integer_sequence<int, Is...> const &)
 { ((std::cout << Is << std::endl), ...); }
like image 149
max66 Avatar answered Sep 29 '22 23:09

max66


If loop limits are known to the compiler, compiler will unroll the loop, if it will find it beneficial. Not all loop unrolls are beneficial! And it is unlikely you will make a better decision than compiler as to benefits of loop unrolling.

There is no need for constexpr for (as you put it), since constexpr if is enabling feature - you may put code which would make program ill-formed inside constexpr if false branch - it is not pure optimization.

Constexpr for, on the other hand, would be pure optimization (at least as you describe it, not counting the fringe case of loop executed 0 times) and as such is better left to 'as-if' optimization rules.

like image 28
SergeyA Avatar answered Sep 29 '22 21:09

SergeyA