假设我有这样的定义类:
template<unsigned int N>
class A { ... }
问题是如何用N?
迭代这些类for(unsigned int i = 0; i < 10; ++i) {
A<i>().doStuff();
}
也许C ++ 11中有一些新功能或者使用 contrexp 。
接下来的问题是:如果有可能 - 如何存储这些类?
更新 我知道它在编译时有效。假设,我有多达10个这样的全局类,它们仅在N中有所不同。例如:
A<1> first;
A<2> second;
A<42> third;
A<1034> fourth;
并且假设,我应该称那个N比我的价值大的人。如果没有机会进行迭代,那么我必须编写长if-else结构。
void doAppropriateStuff(int value) {
if (value < 1) {
first.doStuff();
} else if (value < 2) {
second.doStuff();
} else if (value < 42) {
third.doStuff();
} else if (value < 1034) {
fourth.doStuff();
} else {
...
}
}
希望,问题变得更加清晰。 当我用Google搜索时,这是不可能的,我理解为什么。只希望C ++ 11和SO社区。 感谢。
答案 0 :(得分:10)
使用for循环显然是不可能的,因为它在运行时运行,模板参数需要是编译时常量。这是你怎么做的。
这些是用于构造整数序列作为模板参数包的实用程序类:
template< std::size_t... Ns >
struct indices {
typedef indices< Ns..., sizeof...( Ns ) > next;
};
template< std::size_t N >
struct make_indices {
typedef typename make_indices< N - 1 >::type::next type;
};
template<>
struct make_indices< 0 > {
typedef indices<> type;
};
完成工作的功能:
#include <initializer_list>
template<size_t... Is>
void foo(indices<Is...>)
{
auto list = { (A<Is>().doStuff(), 0)... };
}
你可以这样调用这个函数:
foo(make_indices<10>::type());
答案 1 :(得分:5)
如果您不想依赖c ++ 14的integer_sequence,这是一个更简单的solution:
#include <iostream>
template<unsigned int N>
struct A {
void dostuff() const { std::cout << N << " "; }
};
template < int N > void run();
template <> void run<-1>() {}
template < int N > void run() {
run<N-1>();
A<N>{}.dostuff();
}
int main() {
run<10>();
}
编辑:关于您的问题更新,如果您将对象存储在元组中,则可以执行此操作,请参阅here:
#include <iostream>
#include <tuple>
template<unsigned int N>
struct A {
unsigned int getN() const { return N; }
void dostuff() const { std::cout << N << " "; }
};
auto globals = std::make_tuple( A<3>{}, A<7>{}, A<10>{}, A<200>{} );
template <int idx> void run( int v );
template <> void run<std::tuple_size<decltype(globals)>::value>( int ) {}
template <int idx = 0> void run( int v ) {
auto & a = std::get<idx>(globals);
if ( v < a.getN() ) {
a.dostuff();
} else {
run<idx+1>(v);
}
}
int main() {
for( int i = 0; i<20; ++i)
run( i );
}
答案 2 :(得分:2)
您将使用模板专业化:
template <unsigned int N> struct ADoer
{
static void go() { A<N>().doStuff(); ADoer<N - 1>::go(); }
};
template <> struct ADoer<0>
{
static void go() { }
};