编译时常量enum

在看C++元编程时, 发现基本上都举的这么一个例子:

#include <iostream>
using namespace std;

template <int N>
struct Factorial 
{
    enum  T{ value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

int main()
{
   cout<<Factorial<5>::value<<endl; 
}

我想,能否用其它类型替换enum,我发现static const int是可以代替enum的

#include <iostream>
using namespace std;

template <int N>
struct Factorial 
{
    static const int value = N * Factorial<N - 1>::value;
};

template <>
struct Factorial<0> 
{
    static const int value = 1;
};

int main()
{
   cout<<Factorial<5>::value<<endl; 
}

通过上面2个例子,可以发现不用任何操作,在执行期间可以直接输出value的结构,这是因为在编译期间,value的值已经被计算出来;这也是元编程的本质:在程序编译期间,通过模板生成新的代码,期间完成一些操作。

enum和static const int都是编译时常量,那么enum和static const int的相同点和区别是什么呢?

继续看代码:

#include <iostream>
using namespace std;

template <int N>
struct Factorial 
{
    enum  T{ value = N * Factorial<N - 1>::value };
	static const int value2 = N * Factorial<N - 1>::value2;
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
	static const int value2 = 1;
};

void test(const int &x)
{
  cout<<x<<endl;
}

int main()
{    
    test(Factorial<5>::value);
	test(Factorial<5>::value2); //undefined reference to `Factorial<4>::value2'
}

在代码中增加了void test(const int &x);
当使用static const int测试时,报错:undefined reference to `Factorial<4>::value2', 原因是Factorial<4>::value2在编译时没有生成,就是说没有进行元编程。

具体原因,查了google,长了见识:

Static constant members are lvalues. So, if you have a declaration such as
void test(const int &x)
and you pass it the result of a meta-program
test(Factorial<5>::value2);
a compiler must pass the address of Factorial<5>::value2, which forces the compiler to instantiate and allocate the definition for the static member. As a result, the computation is no longer limited to a pure “compile-time” effect.
Enumeration values aren’t lvalues (that is, they don’t have an address). So, when you pass them “by reference,” no static memory is used. It’s almost exactly as if you passed the computed value as a literal. These considerations motivate us to use enumeration values in all meta-programs.


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值