召唤强人:关于模板偏特化的一个不理解

sunwt 2005-01-06 11:55:18
在《The C++ Programming Language》和《C++ templates》里面都提到过,模板的偏特化有助于减少目标代码的体积,以下摘自《C++ templates》:

Full template specialization is often useful, but sometimes it is natural to want to specialize a class template for a family of template arguments rather than just one specific set of template arguments. For example, let's assume we have a class template implementing a linked list:

template<typename T>
class List { // (1)
public:

void append(T const&);
inline size_t length() const;

};
A large project making use of this template may instantiate its members for many types. For member functions that are not expanded inline (say, List<T>::append()), this may cause noticeable growth in the object code. However, we may know that from a low-level point of view, the code for List<int*>::append() and List<void*>::append() is the same. In other words, we'd like to specify that all Lists of pointers share an implementation. Although this cannot be expressed in C++, we can achieve something quite close by specifying that all Lists of pointers should be instantiated from a different template definition:

template<typename T>
class List<T*> { // (2)
private:
List<void*> impl;

public:

void append(T* p) {
impl.append(p);
}
size_t length() const {
return impl.length();
}

};


既然文中提到all Lists of pointers should be instantiated from the different template definition,那么是针对每一个实参(argument)类型,都会生成一份特殊的实例化体,而如果没有进行过特化的话,也会针对每一个实参(argument)类型,都会生成一份特殊的实例化体,他们两个在生成的目标代码数量上应该是差异极小(在特花实现与范化实现代码相差很大时,目标代码数量差异也会很大,不过既然是同一家族类的同一个函数他们的功能应该是相同的,所以我们假设实现代码规模类似),那怎样减小的目标代码尺寸捏?
...全文
318 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
melonliu 2005-01-08
  • 打赏
  • 举报
回复
学习学习!
sunwt 2005-01-06
  • 打赏
  • 举报
回复
to darkstar21cn(星之魄)(读不懂爱情所以来读程序) ( )
你没有好好读我贴的那段话,文中说的是目标代码,不是你写出来的,是编译器生成的。“this may cause noticeable growth in the object code”原话。

to beyondtkl(大龙驹<*百善孝为先*>)
不是代码规模,是“目标”代码规模

to ilovevc(ilovevc)
就是为了改写成inline的吗?说的有点道理,等等看有没有不同意见。

to playmud(把复杂问题简单化)
你说的没错
playmud 2005-01-06
  • 打赏
  • 举报
回复
另外,建议搂住仔细看看书上写的是不是你理解的意思.
上面提到的是全局特化和局部特化(特化成指针).
playmud 2005-01-06
  • 打赏
  • 举报
回复
我说的不包括: beyondtkl()
playmud 2005-01-06
  • 打赏
  • 举报
回复
你们说得和搂住问的无关吧???
人家问的特化为什么减少目标代码尺寸了,是吧??
ilovevc 2005-01-06
  • 打赏
  • 举报
回复
那是因为对于所有的指针类型,都可以使用List<void*>来实现。
List<void*>的代码只有一份,而对于其他的指针类型,例如List<int*>,内部都可以使用List<void*>的实现,全部函数就可以为inline,无需生成函数调用代码,只需要一个强制转换就可以了。
darkstar21cn 2005-01-06
  • 打赏
  • 举报
回复
如果楼主这么强的人有意见的话,没必要听我这个菜鸟的。
darkstar21cn 2005-01-06
  • 打赏
  • 举报
回复
使用模板并不是说生成的代码少了,而是程序员输入的代码少了。如果没有模板,那么你要自己写的代码量是多少?这是我的理解。
beyondtkl 2005-01-06
  • 打赏
  • 举报
回复
特化的意義之一吧 也是減少代碼規模

但是 更重要的 應該是那個特 字 滿足 特定的參數類型,實現此類功能,而且有些時候必須得特化..

這幾天剛看了一下模板。。學習ing.
darkstar21cn 2005-01-06
  • 打赏
  • 举报
回复
老大,你用std比不用std时,自己写的代码要少了吧?
sunwt 2005-01-06
  • 打赏
  • 举报
回复
我猜想Henry0兄弟也和我开始一样钻牛角尖了,呵呵,希望不是
sunwt 2005-01-06
  • 打赏
  • 举报
回复
to Henry0(Enthusiasm,热情!活着就要有热情!对人,对事,对生) ( ) 信誉:101
你和我开始的想法是一样的,其实最重要的是
void append(T* p) {
impl.append(p);
}
size_t length() const {
return impl.length(); }

复用了List<void*> 的实现代码,而List<void*>只有一份(因为已经针对void*作了全特化),所以减小了目标代码的尺寸。
Henry0 2005-01-06
  • 打赏
  • 举报
回复
刚写完,已经结帖了。
Henry0 2005-01-06
  • 打赏
  • 举报
回复
同意  sunwt(啦啦啦) 的观点

偏特化的主要作用还是为某一类argument类型提供全新的模板定义。

为什么能减少目标代码,我和理解是这样的:


template<typename T>
class List<T*> {
private:
List<void*> impl; //原来应该为List<T*> impl

public:

void append(T* p) {
impl.append(p);
}
size_t length() const {
return impl.length();
}

};


本来如果用到如List<int*>,List<float*>等时,编译器都会为他们生成各自的实例化代码,而当我用
List<void*> impl代替List<T*> impl后,用到如List<int*>,List<float*>等时,就只会使用已有的List<void*> impl,不会针对多种类型实例化出多份代码(因为void*指针是”万能指针“),所以就减少了目标代码。如果我在程序中使用List较频繁,则节省的目标代码还是比较可观的
sunwt 2005-01-06
  • 打赏
  • 举报
回复
咦,怎么结贴?
sunwt 2005-01-06
  • 打赏
  • 举报
回复
哦,我明白了。
感谢星星yjh1982(血精灵)
也感谢也穿一条裤衩的兄弟coolvc2002(cool_vc)

coolvc2002兄弟已经解释的很清楚了,不过我钻牛角尖里了对之视而不见,yjh1982(血精灵)把我拉回来了。


结贴
coolvc2002 2005-01-06
  • 打赏
  • 举报
回复
说了那么多,可能说的还是不清楚,举个例子吧:
假设不使用(2)的特化模板
如果你的一个程序有这样的申明:
List<int*> list_a;
List<char*> list_b;
List<CString *> list_c;
那么编译后代码会展开3个List的code,分别是:List<int*> ,List<char*>,List<CString *>这里就有3份实现代码,编译后代码体积增大,执行速度当然降低了;
但是你如果有(2)的特化模板,再看看(2)的具体实现用到了List<void *>
你就会发现模板展开的代码只有一份List<void *>
当然代码体积减少了。
sunwt 2005-01-06
  • 打赏
  • 举报
回复
to yjh1982(血精灵)
原文是针对void*作了全特化的,贴到后面
Our code contains a problem because List<void*> recursively contains a member of that same List<void*> type. To break the cycle, we can precede the previous partial specialization with a full specialization:

template<>
class List<void*> { // (3)

void append (void* p);
inline size_t length() const;

};
This works because matching full specializations are preferred over partial specializations. As a result, all member functions of Lists of pointers are forwarded (through easily inlineable functions) to the implementation of List<void*>. This is an effective way to combat so-called code bloat (of which C++ templates are often accused).

coolvc2002 2005-01-06
  • 打赏
  • 举报
回复
template<typename T>
class List { // (1)
public:

void append(T const&);
inline size_t length() const;

};

template<typename T>
class List<T*> { // (2)
private:
List<void*> impl; //(3)

public:

void append(T* p) {
impl.append(p);
}
size_t length() const {
return impl.length();
}

};


//=============================================
(2) 是(1)的特化模板,针对指针参数的特化,也就是所谓的:class template explicit specialization,偏特化一般
主要是针对某个类型的参数,进行额外的处理,是基于效率(存储、执行等)和编译速度的考虑,
在这个List 的例子中所有指针类型的,都可以用(void *)来实现,[见(2)实现体的(3)部分]可以针对(void *)进行优化,当然减少了编译时模板展开的代码和时间。
yjh1982 2005-01-06
  • 打赏
  • 举报
回复
减少代码量还得写的人配合才可以.
比方用List<void*> impl; 实现了大部分运算.
如果List<void*>的相关代码放在
template<typename T>
class List<T*>中,就不会减少代码量
加载更多回复(2)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧