模板元编程 – 使用Enum Hack和Static Const之间的区别

我想知道使用模板元编程技术时,使用静态常量和枚举黑客之间有什么区别。

EX:(通过TMP的斐波纳契)

template< int n > struct TMPFib { static const int val = TMPFib< n-1 >::val + TMPFib< n-2 >::val; }; template<> struct TMPFib< 1 > { static const int val = 1; }; template<> struct TMPFib< 0 > { static const int val = 0; }; 

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

为什么使用一个呢? 我已经读过enum hack是在类内部支持static const之前使用的,但是为什么现在要使用呢?

枚举不是lvals,静态成员值是,如果通过引用传递模板将被instanciated:

 void f(const int&); f(TMPFib<1>::value); 

如果你想做纯粹的编译时间计算等,这是一个不希望的副作用。

主要的历史差异是枚举也适用于不支持成员值的类初始化的编译器,现在大多数编译器都应该修正这个问题。
枚举和静态常量之间的编译速度也可能有所不同。

增强编码指南中有一些细节,增强档案中有关该主题的较旧线程 。

对于某些人来说,前者可能看起来不那么黑客,更自然。 另外,如果你使用这个类,它也会为它自己分配内存,所以你可以拿val的地址。

后者得到了一些较老的编译器的更好的支持。

在@Georg的答案的另一面,当一个包含一个静态常量variables的结构被定义在一个专门的模板中时,它需要在源代码中声明,以便链接器可以find它,并且实际上给它一个地址以供引用。 这可能会不必要地(取决于所需的效果)导致不雅的代码,尤其是如果你正在尝试创build一个只有标题的库。 您可以通过将值转换为返回值的函数来解决这个问题,也可以将模板打开到运行时信息。