编译时常量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
    评论
在C语言中,`typedef enum`是**结合了typedef和enum两个关键字来创建一个新的枚举型别名的方法**。 首先,让我们分别了解typedef和enum的基本概念: - **Enum(枚举)**:枚举是C语言中的一种数据型,用于声明一组命名的整数值。它提供了一种方式来定义一个变量,这个变量只能从预定义的一组值中选取。例如,可以定义一个枚举型来表示一周的七天,或者不同的颜色等。 - **Typedef**:typedef是C语言的一个关键字,它允许程序员为现有的数据型创建一个新的名称。这样做的目的是提高代码的可读性和方便性。例如,可以用typedef为int型创建别名,如`typedef int INTEGER;`,之后就可以用INTEGER代替int来声明变量。 当结合使用typedef和enum,可以创建一个新的枚举型的别名。这样做的好处是,可以在程序中多次使用这个别名来声明枚举型的变量,而不需要每次都写出整个枚举型的定义。这不仅可以减少打字工作量,还可以提高代码的清晰度和一致性。 此外,在使用typedef和enum,需要注意以下几点: - **Typedef不产生新型**:typedef只是为现有型提供了一个新的名称,它并不创造新的数据型。 - **Enum的值是常量**:通过enum定义的值是真正的常量,它们在编译被分配具体的整数值。 - **使用typedef enum的注意事项**:在使用typedef为enum定义别名,应该确保别名的名称清晰地反映了它所代表的枚举型的含义,以避免混淆。 综上所述,`typedef enum`在C语言中是一个强大的工具,它允许程序员创建易于理解和使用的枚举型别名,从而提高代码的可维护性和可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值