template的技术内在???

一杯鲜橙多 2013-05-15 09:35:36
最近看到template的东西,有些语法有稍微不解,希望有人能剖析一下。以下引用一些template的写法:
template <typename valType>
class BTnode {
public:
BTnode( const valType &val );
private:
int _cnt; // occurrence count
valType _val;
BTnode *_lchild;
BTnode *_rchild;
void display_val( BTnode *pt, ostream &os ) const;
BTnode( const BTnode& );
};

template <typename valType>
inline
BTnode<valType>::
BTnode( const valType &val )
: _val( val )
{
_cnt = 1;
_lchild = _rchild = 0;
}

这是关于class template将处理的“type“抽象出来,是第一种参数化其型别。
template <int pos>
class num_sequence {
public:
virtual ~num_sequence(){};
int elem( int pos ) const;
protected:
virtual void gen_elems( int pos ) const = 0;
bool check_integrity( int pos, int size ) const;
//...
};

这是第二种non-type参数化模板,被template掉的是const expression。
BTnode<double> instance;
num_sequence<5> instance;

两者的使用时,第一种将type传入,编译器构造一份该type的模板实例,第二种将一个对应的const expression传入,编译器将产生一份该类实例,len变成5.

以上都还好理解,下面的就让我开始糊涂了,诸位请看:
template<void (*p)(int, double)>
class A{
public:
A(int len, double rate):_len( len ), _rate( rate)
{
if(!p)
;//error message here.
p(_len, rate);
}
//...other methods here.
private:
int _len;
double _rate;
};

//using in client
void cal(int len, double rate);
A<cal> instance;


此处将globe defined的函数指针试作const expression,在使用class A的时候,以模板实参传入,编译器将把该份A实例中的p替换成cal,而cal为指针入口,那么A实例将调用cal方法,大概是这样的意思。
到这里为止,我开始有一点点迷糊,但是还想得通,如果所有的东西是const expression,那么用来构造模板实例也不是很过分。

下面就晕了。
template<typename elemType, typename Comp = less<elemType> >
class LessThanPred{
public:
LessThanPred( const elemType &val ):_val( val ){ }
bool operator()( const elemType &val ) const
{ return Comp( val, _val );}//此处迷糊

void val(const elemType &val) { _val = val; }
elemType val() const { return _val; }
private:
elemType _val;
};

class StringLen{
public:
bool operator()( const string &s1, const string s2 )
{
return s1.size() < s2.size();
//test++;
}
//private:
//int test;
};

LessThanPred<int> ltpi(1024);
LessThanPred<string, StringLen> ltps("Pooh");

if(ltps("abc")) ;//something


以上用typename,那么被抽象的是type,而非const expression。
为type ”Comp“指定了一个标准库的两元比较function object"LessThan<elemType>"默认值,当然后面自己写了一个StringLen的function object。在模板里面有Comp(val, _val);这样的语句调用。
我试图这样去解释:
首先编译器以StringLen类型为该模板制造一份实例,Comp(val, _val)则变成StringLen(val, _val)。
目的是希望调用到StringLen的operator(),这个function call运算符号。
要调用到StringLen 的operator(),我们需要StringLen的实例。
编译器难道在模板化LessThanPred的时候,构造了一个StringLen实例???这个和之前Bnode<double>模板的处理明显不同,后者只是类型替换一下罢了。。。

谁知道template机制到底概观是个什么样的模式,分几块?具体实现的细节能提一下么?不然我感觉自己理解不下去了。后面还有template member function什么的,还有个种template模板技术组合使用。
...全文
177 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-05-16
  • 打赏
  • 举报
回复
template<typename elemType, typename Comp = less<elemType> > class LessThanPred{ public: LessThanPred( const elemType &val ):_val( val ){ } bool operator()( const elemType &val ) const { return Comp( val, _val );}//此处迷糊 void val(const elemType &val) { _val = val; } elemType val() const { return _val; } private: elemType _val; }; class StringLen{ public: bool operator()( const string &s1, const string s2 ) { return s1.size() < s2.size(); //test++; } //private: //int test; }; LessThanPred<int> ltpi(1024); LessThanPred<string, StringLen> ltps("Pooh"); if(ltps("abc")) ;//something if(ltps("abc")) -->bool operator()( const elemType &val ) const {return Comp( val, _val );}-->Comp( val, _val ); --> StringLen(val, _val)-->StringLen()(val, _val); -->StringLen::operator()(val, _val); ---> bool StringLen::operator()( const string &s1, const string s2 ) { return s1.size() < s2.size(); //test++; }
ztenv 版主 2013-05-16
  • 打赏
  • 举报
回复
楼主看得有点深了,先从简单的看起,循序渐近吧
www_adintr_com 2013-05-16
  • 打赏
  • 举报
回复
书上的也不一定 100% 正确呀, 你去找一下这本书的勘误表看, 有么有对这个的修正, 没有的话可以向他提一个 BUG 了.
一杯鲜橙多 2013-05-16
  • 打赏
  • 举报
回复
引用 6 楼 adlay 的回复:
你在哪里找的 LessThanPred 定义? 难怪你不能理解, 因为它就是错的.
您是指Comp(val, _val)一句吗? 我开始的思考也是这一句应该写成Comp()(val, _val),需先有实例对象,才能调用那个方法。 不过这段代码是从Essential C++当中拿到的,见第6章,以template进行编程。我读的是一本侯捷老师翻译的电子版书籍,所以才拿到这里问问。足下何解?
一杯鲜橙多 2013-05-16
  • 打赏
  • 举报
回复
引用 3 楼 nirvana_newbie 的回复:
less<>的方法:http://technet.microsoft.com/zh-cn/library/e2bbwta4(v=vs.71) 你糊涂的是template<typename elemType, typename Comp = less<elemType> >这种用法,在调用的时候 LessThanPred<int> ltpi(1024);为什么只有一个参数,因为Comp被默认赋值为less<elemType> 这有什么难以理解的?LessThanPred<int> ltpi(1024);这句elemType为int LessThanPred<string, StringLen> ltps("Pooh");这句elemType为string,第二个参数Camp=StringLen,调用Camp()时,就是调用StringLen类的()运算符重载函数呗。
非也,乃是Comp(val, _val);
一杯鲜橙多 2013-05-16
  • 打赏
  • 举报
回复
引用 1 楼 taodm 的回复:
先去看《stl源码剖析》,再看《modern c++ design》,再回来看这个书
这个事后话了吧,我估计我现在水平还是暂时不去看那个书,留待后面。
www_adintr_com 2013-05-16
  • 打赏
  • 举报
回复
你在哪里找的 LessThanPred 定义? 难怪你不能理解, 因为它就是错的.
nirvana_newbie 2013-05-15
  • 打赏
  • 举报
回复
less<>的方法:http://technet.microsoft.com/zh-cn/library/e2bbwta4(v=vs.71) 你糊涂的是template<typename elemType, typename Comp = less<elemType> >这种用法,在调用的时候 LessThanPred<int> ltpi(1024);为什么只有一个参数,因为Comp被默认赋值为less<elemType> 这有什么难以理解的?LessThanPred<int> ltpi(1024);这句elemType为int LessThanPred<string, StringLen> ltps("Pooh");这句elemType为string,第二个参数Camp=StringLen,调用Camp()时,就是调用StringLen类的()运算符重载函数呗。
bluewanderer 2013-05-15
  • 打赏
  • 举报
回复
return Comp( val, _val ) <- 是return Comp()( val, _val )吧?
taodm 2013-05-15
  • 打赏
  • 举报
回复
先去看《stl源码剖析》,再看《modern c++ design》,再回来看这个书

65,206

社区成员

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

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