在c++ 11中迭代模板类
Iterate over template classes in c++ 11
假设,我有这样定义的类:
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 {
...
}
}
希望,问题变得更清楚了。当我在谷歌上搜索时,这是不可能的,我明白为什么。只寄希望于c++ 11和SO社区。谢谢。
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());
如果您不想依赖c++14中的integer_sequence,这是一个更简单的解决方案:
#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>();
}
编辑:关于你的问题更新,你可以这样做,如果你将对象存储在一个元组中,见这里:
#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 );
}
您可以使用模板专门化:
template <unsigned int N> struct ADoer
{
static void go() { A<N>().doStuff(); ADoer<N - 1>::go(); }
};
template <> struct ADoer<0>
{
static void go() { }
};
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 迭代时从向量和内存中删除对象
- 如何在c++迭代器类型中包装std::chrono
- 带过滤器的现代迭代c++集合
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- C++矢量迭代
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 擦除while循环中迭代的元素
- 实现一个在集合上迭代的模板函数
- 对于set上的循环-获取next元素迭代器
- 在向量内的向量上迭代
- 为什么output_editor Concept不需要output_e迭代器标记
- TSP递归解的迭代形式
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器