在c ++ 11中迭代模板类

时间:2014-03-25 17:30:37

标签: c++ templates c++11 constexpr

假设我有这样的定义类:

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社区。 感谢。

3 个答案:

答案 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() { }
};