c++ - 递归模板不能像预期的那样使用静态变量

标签 c++ templates visual-c++ recursion static-members

代码

#include <iostream>
using namespace std;

template<int n> struct Fibo { static int x; };
template<> int Fibo<0>::x = 1;
template<> int Fibo<1>::x = 1;
template<int n> int Fibo<n>::x = Fibo<n-1>::x + Fibo<n-2>::x; //marked line

int main() {
    cout << Fibo<5>::x << endl;
    cout << Fibo<4>::x << endl;
    cout << Fibo<3>::x << endl;
    cout << Fibo<2>::x << endl;
    cout << Fibo<1>::x << endl;
    cout << Fibo<0>::x << endl;

    return 0;
}

输出

0
0
1
2
1
1

在 VC++ 中。 (根据用户 M M. 它在 gcc 中按预期编译)。当编译器到达带有 n=5 的标记行时它不会为 n=4 再次编译同一行, 但只是对待 Fibo<4>::x就好像它是用

声明的一样
template<> int Fibo<4>::x; // x defaults to 0

这是为什么呢?为什么在使用的时候可以正常使用

template<int n> struct Fibo { enum { x = Fibo<n-1>::x + Fibo<n-2>::x }; };
template<> struct Fibo<0> { enum { x = 1 }; };
template<> struct Fibo<1> { enum { x = 1 }; };

而不是静态变量?你如何修复第一个代码(没有 enum )?

最佳答案

标准对此非常明确:

14.7.1 Implicit instantiation [temp.inst]

9 The implicit instantiation of a class template does not cause any static data members of that class to be implicitly instantiated.

main() 中的所有调用给你的Fibo<n>::x对于 n > 1 , 是显式实例化,通过 Fibonnaci 递归将隐式实例化 Fibo<n-1>Fibo<n-2>但不是他们的成员x .这意味着在这些点上,static成员x将被评估为其默认初始化 0 .对于 n=1n=0 ,编译器将看到 1 的显式初始化值。如此有效,您可以得到以下计算

Fibo<5>::x --> Fibo<4>::x + Fibo<3>::x --> 0 + 0 = 0
Fibo<4>::x --> Fibo<3>::x + Fibo<2>::x --> 0 + 0 = 0
Fibo<3>::x --> Fibo<2>::x + Fibo<1>::x --> 0 + 1 = 1
Fibo<2>::x --> Fibo<1>::x + Fibo<0>::x --> 1 + 1 = 2
Fibo<1>::x --> 1
Fibo<0>::x --> 1

您需要实例化静态成员x在评估 Fibonacci 递归之前。您可以通过 static const int 来做到这一点或 enum成员(member)x ,或通过 @Jarod42 所示的函数(在 C++11 中可能是 constexpr)。

关于c++ - 递归模板不能像预期的那样使用静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19345033/

相关文章:

c++ - DirectX10 交换链和设备指向 0x00000000(导致运行时错误)(c++)

ruby - 如何使用 Ruby 和 Builder::XMLMarkup 模板生成 XML 文件?

c++ - 使用模板元编程提供强类型坐标系

c++ - 在模板初始化期间,模板参数列表中的 false 评估为什么?

c++ - 是否可以从混合的 C++/CLI 代码中调用 IronPython?

c++ - 通过命令行编译C/C++/Visual C程序

c++ - 声明指向多维数组的指针并分配数组

c++ - 类方法的函数对象

c++ - 标准输入作为 MSVC 的输入文件

c++ - 如何将 ATL/MFC CString 转换为 QString?