理想与现实之间

学习的最好方法就是blog

博客园 首页 新随笔 联系 订阅 管理
  68 随笔 :: 0 文章 :: 429 评论 :: 17万 阅读

今天在书店里翻 "C++ template" 学习了一下以前一直不明白的Metaprogramming,发现原来就是那个在模板里加enum的技巧的应用,仔细想一下果然可以衍生出很多用途,下面是一个最简单的例子:
#include <iostream>
using namespace std;

template<int n>
class twoPower
{
public:
 enum { result = 2*twoPower<n-1>::result };

};

template<>
class twoPower<0>
{
public:
 enum {result = 1};
};

int main()
{
 cout << twoPower<5>::result <<endl;
}

定义了一个用来算2的n次方的模板,用了模板的特化来做为递归的终止条件。第一次接触到这样形式的模板应用是在"Modern C++ Design" 的typelist里,当时就非常的惊讶,发现C++的表达能力实在是我无法想像的。

今天,书店里思考了一会儿,觉得这个技术可以用来在编译期实现类似.net中attribute的东西。回来在机器上试了一下,像这样:
首先定义一个attribute的模板类,并提供一个默认值:

template<typename T>
class SerializableAttribute
{
public:
 enum { IsSerializable = 0 };
};

然后你定义了一个自己的类,比如这样:

class
myClass
{
};

为了应用上面的那个Attribute,你需要为你的类提供一个特化:

template<>
class SerializableAttribute<myClass>
{
public:
 enum {IsSerializable = 1 };
};

然后,在其它地方就可能用到这个attribute。(reflect吗? )

int main()
{
 if (SerializableAttribute<myClass>::IsSerializable) cout << "myClass can be serialized." <<endl;
 else cout <<"myClass can't be serialized" <<endl;
}

我想以上这种应用,应该就是这种技术被称为metaprogramming的原因吧。这样的Attribute和.net中的Attribute最大的大区别是它是静态的,因为模板的推导工作全部都是在编译期完成的,而不是像.net中那样将metadata编译进assembly里,然后再在执行期运用反射来获取。这当然会使得它的用途受到诸多限制。

不过有时候我在想,像C++这样缺乏运行时支持,到底是劣势呢?还是优势呢? 最近在研究C#2.0中的泛型机制,其中新提出来的 约束 的机制,我个人猜测很可能就是因为C#太强大的反射机制,导致泛型的推导,不能像C++那样完全在编译期完成,才不得不加上的。

C++中的编译期多态,在C#中似乎也没有办法使用了。不过说不定加入泛型的C#,又会生出许多新的应用,谁知道呢! 当初为C++加入模板的时候,stroustup教授自己恐怕也没有想到泛型会有今天的发展吧。语言总会给我们带来惊喜,谁说不是呢。

posted on   Justin Shen  阅读(1169)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示