I am trying to write a C++ loop that I want evaluated at compile-time. This is because I need to use the looping variable as a template argument to initialize a class. In the very simple case it would look something like:
for (unsigned int i = 1; i < 8; i++) {
Vector<i> foo;
// do something with foo
}
After going through some similar StackOverflow questions, I found a way to write a static for loop recursively. Now my code looks something like this:
template <unsigned int i, unsigned int end>
struct static_for {
template <typename Lambda>
void operator()(const Lambda& function) const {
if (i < end) {
function(i);
static_for<start + 1, end>(function);
}
}
};
template <int N>
struct static_for<N, N> {
template <typename Lambda>
void operator()(const Lambda& function) const {
// This is just to avoid the unused variable warning - does nothing.
(void)function;
}
};
This works perfectly and as expected. In order to call this static_for
loop I can simply write:
static_for<0, 8>()([](int size) {
// some code here.
});
The problem, however, is that I can still not evaluate i
at compile time. As in I cannot create a templated object within the lambda expression:
static_for<0, 8>()([](int size) {
Vector<size> var; // does not compile as size is not a constexpr.
});
How can I make this work? My static_for
loop has the i
variable as a template argument which is available to it at compile time. I would like my lambda expression to receive this argument (size
) also at compile time rather than being passed in as a runtime variable. How would this work? Conceptually this seems simple and useful as a more general language feature as well.
If you can use C++14, you could pass an
std::integral_constant
to a generic lambda instead of anint
. gcc.godbolt.org exampleI've made a bit different solution based on @Vittorio Romero's answer which should work with c++11 and g++ 4.9. You can run it here. In @Vittorio's solution you have to define
Lambda
function outside block scope due tointegral_constant
(see example code in comments) use. In my solution you have more lambda-like behaviour. You can define your structure within other function and pass to it any number of arguments.[EDIT] Ok, it was a bit too late for my mind work ;) Unfortunately I can't come out with a type of lambda-like solution to work in compile-time. So you have to define your lambda structures outside block scope. You can run modified code here.