读书笔记:Effective C++ 炒冷饭 - Item47 traits:类型信息榨取机

读书笔记:Effective C++ 炒冷饭 - Item47 traits:类型信息榨取机
[原创文章欢迎转载,但请保留作者信息]
Justin 于 2010-05-11

看到题目我笑了,原来traits也被大师归为55式不外传神功之一。看来当初花的时间还是值得的啊@#¥%

貌似谈到traits都要扯上STL、Boost,大师这回也未能免俗。开课就先介绍5种迭代器,input_iterator, output_iterator, forward_interator, bidirectional_iterator 和random_access_iterator。不过我不想再走老路了,还是自己杜撰些东东来比较好玩。

大师说:traits首先应该是个结构体(struct),然后是个被当作类来用的结构体,因为用了公有继承来表示以上5种迭代器的关系(@#$%)
Traits 也叫“Baggage Class”(Nathan C. Myers, C++ Report, June 1995)。在我看来,traits可以理解为类型信息榨取机,制造它的过程大致分以下几步,这里来个简单的例子,我们以不同食物的好吃/不好吃作为食物的类型:

1、既然和类型信息有关,首先需要知道所有可能的类型(如果是void,int之类的已经类型,就可以忽略此步骤),我们的食物有一下两种类型:
struct  yummy {};
struct  yucky {};

2、用一个模板化的traits结构体来构造用于榨取类型信息的“吸管”:
template  < typename T >
struct  food_traits
{
    typedef typename T::Taste taste;
};

上面的“吸管”用来得到某种食物的好吃/不好吃属性。“吸管”能工作的前提是:某食物类一定要有这一属性,要么好吃(yummy)要么不好吃(yucky)。

3、然后根据不同的食物制定不同的模板函数的重载:
template  < typename T >
string  doTry ()
{
    
return   " well, i don't know what this is but i will till take a try.. " ;
}

template 
< typename T >
string  doTry(T & , yummy)
{
    
return   " of course i like this! " ;
}

template 
< typename T >
string  doTry (T & , yucky)
{
    
return   " no,keep it away from me.. " ;
}

4、当然,每个“食物”在制作的过程中也要加入好吃/不好吃的元素:
class  Cheeseburg
{
    
public :
        typedef yummy Taste;
    
// ..
};

class  Wasabi
{
    
public :
        typedef yucky Taste;
    
// ..
};

5、最后……当然就是品尝食物咯~~
int  main()
{
    Cheeseburg C;
    Wasabi W;

    cout 
<<   " Cheeseburg? : "   <<  doTry(C, food_traits < Cheeseburg > ::taste())  <<  endl;
    cout 
<<   " Wasabi?         : "   <<  doTry(W, food_traits < Wasabi > ::taste())  <<  endl;

    
return   0 ;
}

这个例子比较STL或是其他的真实例程来说比较简单明了,而且有我爱吃的芝士堡,希望你也喜欢:)

不过在大师的课堂里,其实还有一步。为了使调用第3步中的重载模板函数更简单,隐藏不必要的细节,我们可以再加上一层wrapper函数:
template  < typename T >
string  Try(T &  food)
{
    
return  doTry(food, typename food_traits < T > ::taste());
}

然后上面的调用就简化为:
// ..
cout  <<   " Cheeseburg? : "   <<  Try(W)  <<  endl;
cout 
<<   " Wasabi?         : "   <<  Try(C)  <<  endl;
// ..

你可能感兴趣的:(读书笔记:Effective C++ 炒冷饭 - Item47 traits:类型信息榨取机)