注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

暇隙读书(5)——STL源码剖析之一模板的宏定义  

2013-04-18 10:52:22|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

暇隙读书(5)——STL源码剖析之一模板的宏定义

源码剖析的第一章对几个宏定义进行了注解,有些地方觉得不是很清楚,这里再重复一下:

 

1. __STL_STATIC_TEMPLATE_MEMBER_BUG

#   if __GNUC__ == 2 && __GNUC_MINOR__ <= 7

#     define __STL_STATIC_TEMPLATE_MEMBER_BUG

#   endif

为什么会有这个定义?因为GNU C++编译器在2.7版本之前都存在这样一个bug :模板类static 的成员变量不能正常的初始化

template<class T>

class Test

{

    public:

        static T data;

};

 

int  Test<int>::data = 5;

以上这一句看似很平常的初始化在GNU C++2.7版本之前不能得到预期想要的结果,在GNU C++2.8及以后版本中被修正

已经在VC2005中尝试,没有此BUG

 

2. __STL_CLASS_PARTIAL_SPECIALIZATION

 正常的template class的使用当然大部分编译器都能支持,但是存在一些特殊的template class 的使用方法,举例如下:

 

 template <class I, class O>

struct Test

{

    Test() {cout << "I, O" << endl;}

};

 

template<class T>

struct Test<T*, T*>

{

    Test() {cout << "T*, T*" << endl;}

};

 

template<class T>

struct Test<const T*, T*>

{

    Test{cout << "const T*, T* << endl; }

}

 

void main()

{

    Test<int, char>    a;

    Test<int*, int*>    b;

    Test<const int*, int*> c;

}

 

把编译器的对这种模板的支持叫做“类模板的偏特化”

已经在VC2005中尝试,支持此特性

[参考] C++ Template 12.4 Class Template Partial Spetialization

 

3. __STL_FUNCTION_TMPL_PARTIAL_ORDER

 

该宏用来表示编译器是否支持函数模板偏序规则

[参考] C++ Template 12.2 Partial Ordering of Overloaded function Templates

 

4. __STL_MEMBER_TEMPLATES

 

该宏用来表示编译器是否支持在template class中还存在template function

 

class alloc

{

};

 

template <class T, class Alloc=alloc>

class vector

{

    typedef T  value_type;

    typedef value_type* interator;

 

    template <class I>

    void insert(interator position, I first, I last)

    {

        cout << "insert" << endl;

    }

};

 

void main()

{

    int ia[] = {0, 1, 2, 3, 4};

    vector<int> a;

    vector<int>::interator it;

    a.insert(it, ia, ia+5);

}

 

5. __STL_LIMITED_DEFAULT_TEMPLATES

 

该宏用来表示编译器是否支持根据前一个模板参数来设置后一个模板参数的默认值

 

template <class T, class Alloc=alloc<T>>

class vector

{

    ...

};

 

6. __STL_NON_TYPE_TMPL_PARAM_BUG

 

 该宏用来表示编译器是否支持非类型的模板参数

 

template <class T, class Alloc=allc, size_t bufsize>

class vector

{

    ...

};

 

7. __STL_NULL_TMPL_ARGS

 

# ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS

#   define __STL_NULL_TMPL_ARGS <>

# else

#   define __STL_NULL_TMPL_ARGS

# endif

 

8. __STL_TEMPLATE_NULL

 

# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \

     || defined (__STL_PARTIAL_SPECIALIZATION_SYNTAX)

#   define __STL_TEMPLATE_NULL template<>

# else

#   define __STL_TEMPLATE_NULL

# endif

 

用于类模板的显式特化(class template explicit specialization

 

template <class Key> struct hash {};

template <> struct hash<char> {};

template <> struct hash<unsignd char> {};

 

注意上面的使用,如果你直接使用标准库的头文件,这个没问题,如果你是自己模拟重新定义,请将结构体的名字改一下,否则会报:

 

1>d:\vs2010_project\testmaro\testmaro\testmaro.cpp(35): error C2872: hash: 不明确的符号

 

1>          可能是“d:\vs2010_project\testmaro\testmaro\testmaro.cpp(29) : hash

 

2>                                          d:\vs2010\vc\include\xfunctional(763) : std::hash

 

另外大家注意,好多的模板使用的是struct 而不是使用class,目的是为了提供一个public的访问方式,在traits中非常明显。

 

注意和模板元编程的区别:

 

//模板元编程

 

template<int n> struct Fib 

 

{

 

    enum { val = Fib<n-1>::val + Fib<n-2>::val };

 

};

 

 

 

template<> struct Fib<0>

 

{

 

    enum { val = 0 };

 

};

 

 

 

template<> struct Fib<1>

 

{

 

    enum { val = 1 };

 

};

 

int _tmain(int argc, _TCHAR* argv[])

 

{

 

       cout<<Fib<5>::val<<endl;//5 

 

    cout<<Fib<20>::val<<endl;//6765

 

       getchar();

 

       return 0;

 

}

 

后者和前者有着密切的关系。

  评论这张
 
阅读(813)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017