C ++元编程热切评估

时间:2013-10-14 16:37:45

标签: c++ recursion template-meta-programming

这是我目前的代码:

template<int n>
struct N{
    static const int k = (n >= 2) ? (1 + N<n-2>::k) : N<0>::k;
};

template<>
struct N<0>{
    static const int k = 0;
};

以下编译:

int main(int, char *[])
{
    cout << N<2>::k;
    getchar();
}

以下内容无法编译:

int main(int, char *[])
{
    cout << N<1>::k;
    getchar();
}

编译器是否急切地计算?:运算符的正确分支?如果是这样,我怎么能懒得评价呢?

3 个答案:

答案 0 :(得分:5)

如果您打算使用模板专业化,那就是我在整个过程中使用的内容:

template<int n>
struct N{
    static const int k = 1 + N<n-2>::k;
};

template<>
struct N<1>{
    static const int k = 0;
};

template<>
struct N<0>{
    static const int k = 0;
};

除非您已经开始使用模板执行此操作,否则我通常更喜欢以下内容:

int constexpr N(int n) { return n/2; }

答案 1 :(得分:1)

使这个例子有效:

template<int n>
struct N{
    static const int k = 1 + N<n-2>::k;
};

template<>
struct N<1>{
    static const int k = 0;
};

template<>
struct N<0>{
    static const int k = 0;
};

问题在于N<n-2>。当n=1时,这将导致无限模板实例化深度。所以这只能部分回答这个问题,但我认为你不能强迫模板进行延迟评估。

答案 2 :(得分:1)

这似乎有效,可以很容易地推广到需要用惰性求值结构替换三元运算符?的情况:

#include <iostream>

template<int n, bool = (n >= 2)>
struct N;

template<>
struct N<0, false>{
    static const int k = 0;
};

template<int n>
struct N<n, true> {
    static const int k = 1 + N<n-2>::k;
};

template<int n>
struct N<n, false> {
    static const int k = N<0>::k;
};

int main() {
    std::cout << N<2>::k << '\n'; 
    std::cout << N<1>::k << '\n';
}

但是,使用C ++ 11 constexpr函数时,此实现已过时。