I am looking for a definition of constants (n) allowing them to be used as parameter in a template constructor, eg. something like this:
const int n[5] = { 4, 8, 16, 32, 64 };
for (int i = 0; i < 5; i++)
{
SomeClass<n[i]> C;
(...other things depending on n[i])
}
SomeClass looks like
template<int n> class SomeClass {...}
Is there any way to this (using macros or anything else)?
Yes, you can do this by using recursive templates to do the looping and specifying n
as a constexpr
. This will only work in C++11 or greater. Working example ( ideone link ):
#include <type_traits>
template <int n>
class SomeClass
{
// debug function for example
public:
void debug() {
cout << "SomeClass<" << n << ">" << endl;
}
};
constexpr int n[5] = { 4, 8, 16, 32, 64 };
template <int i>
struct loop
{
static void doit()
{
SomeClass<n[i]> C;
C.debug();
// other things depending on n[i]
loop<i+1>::doit();
}
};
// close out the iteration
template <>
struct loop<std::extent<decltype(n)>::value>
{
static void doit()
{
}
};
int main() {
loop<0>::doit();
return 0;
}
Output:
SomeClass<4>
SomeClass<8>
SomeClass<16>
SomeClass<32>
SomeClass<64>
It's not possible with that for
loop. The reason is simple: n[i]
inside the loop is not a constant expression. i
could change inside the loop in different ways and the information about whether to instantiate a specific instance of SomeClass
or some other is runtime-dependent.
You can use template meta programming instead:
template <int from, int to>
struct for_ {
template<template<int> class Fn>
static void run() {
Fn<from>::run();
for_<from + 1, to>::template run<Fn>();
}
};
template <int to>
struct for_<to, to> {
template<template<int> class Fn>
static void run() {}
};
We can then define our own utilities:
template <int n>
struct SomeClass {};
constexpr int n[5] = { 4, 8, 16, 32, 64 };
template<int i>
struct functor {
static void run() {
SomeClass<n[i]> c;
// something else
}
};
and use it as:
int main() {
for_<0, 5>::run<functor>();
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.