Is there a solution like this to loop over a function with a templated int parameter that doesn't require creating a new struct with a body() function any time forIdx is needed with a new function? Templated lambdas in C++20 seemed promising, but it didn't seem possible to specify template parameters that aren't automatically deduced.
struct LoopFunc {
template <int i>
void body() {
std::cout << i;
};
};
template<int i>
struct forIdx {
template<typename T>
static void loop(T&& func) {
func.body<i>();
forIdx<i - 1>::loop(func);
}
};
template<>
struct forIdx<-1> {
template<typename T>
static void loop(T&& func) {};
};
int main() {
forIdx<10>::template loop(LoopFunc{});
}
The function is used to create a cartesian product of tuple elements. DirectProduct contains elements that all have a static generateAllElements() function.
struct CrossProduct {
std::tuple<MockElement...> vals;
std::set<DirectProduct> result;
template <int num>
void body() {
if (result.empty()) {
for (const auto& e2 : std::get<num>(vals).generateAllElements()) {
DirectProduct tmp;
std::get<num>(tmp.vals) = e2;
result.insert(tmp);
}
}
else for (const DirectProduct& e1 : result)
for (const auto& e2 : std::get<num>(vals).generateAllElements()) {
DirectProduct tmp = e1;
std::get<num>(tmp.vals) = e2;
result.insert(tmp);
}
};
};
DirectProduct uses the CrossProduct in its own generateAllElements() function
std::set<DirectProduct> generateAllElements() const {
CrossProduct crossProduct{ };
forIdx<std::tuple_size<std::tuple<MockElement...>>::value - 1>::template loop(crossProduct);
return crossProduct.result;
};