代码改变世界

C++中的Traits技法

2016-08-12 16:37  shuaihanhungry  阅读(474)  评论(0编辑  收藏  举报

Traits广泛应用于标准程序库。Traits classes使得“类型相关信息”在编译期可用。
认真读完下面的示例,你应该就懂了Traits技法,其实并不难。

#include <bits/stdc++.h>
using namespace std;

//1,确认若干你希望将来可取得的类型相关信息
struct TypeOneTag {};
struct TypeTwoTag {};
struct TypeThreeTag: public TypeTwoTag {};
struct TypeFourTag: public TypeThreeTag {};

//2,在你将使用的类中为该信息选择一个名称
class ClassOne {
public:
    typedef TypeOneTag TypeCategory;
};

class ClassTwo {
public:
    typedef TypeTwoTag TypeCategory;
};

class ClassThree {
public:
    typedef TypeThreeTag TypeCategory;
};

class ClassFour {
public:
    typedef TypeFourTag TypeCategory;
};

//3,提供一个template和一组特化版本
template<typename T>
struct TypeTraits {
    typedef typename T::TypeCategory TypeCategory;
};

template<typename T>
struct TypeTraits<T*> {
    typedef TypeOneTag TypeCategory;
};

//4,建立一组重载函数(身份像劳工)或函数模板,彼此间的差异只在于各自的traits参数
void doSomething(TypeOneTag) {
    cout << "TypeOneTag" << endl;
}

void doSomething(TypeTwoTag) {
    cout << "TypeTwoTag" << endl;
}

void doSomething(TypeThreeTag) {
    cout << "TypeThreeTag" << endl;
}

//5,建立一个控制函数(身份像工头)或函数模板,它调用上述那些“劳工函数”并传递traits class所提供的信息
template<typename T>
void test(T t) {
    doSomething(typename TypeTraits<T>::TypeCategory());
}

//测试
int main(){
    ClassOne one; test(one);       //TypeOneTag
    ClassTwo two; test(two);       //TypeTwoTag
    ClassThree three; test(three); //TypeThreeTag
    ClassFour four; test(four);    //TypeThreeTag,继承关系带来的一项红利,这也是public继承带来的部分好处
    int *pointer; test(pointer);   //TypeOneTag

    return 0;
}

参考:《Effective C++》、《STL源码剖析》。