CPP Templates 之 技巧性基础知识

1.关键字typename
在C++标准化过程中,引入关键字typename是为了说明:模板内部的标识符可以是一个类型,譬如下面的例子:

template<typename T>
class MyClass{
    typename T::SubType * ptr;
    ...
};
template <class T>
class MyClass
{
    typename T::SubType 8 ptr;
    //...
}
SubType成为一个型别的条件是,任何一个用来取代T的类型,
其内部都必须提供一个内部型别(inner type)SubType,例如
MyClass<Q> x;
必要条件是型别Q有如下的内部型别定义:
class Q{
    typedef int SubType;
    //...
}
或者
class Q{
    class SubType;
}

2.template构造

考虑下面标准bieset模板的例子
template<int N>
void printBitset(std::bitset<N> const& bs)
{
    std::cout<<bs.template to_string<char,char_traits<char>,allocator<char>>();
}
只有编辑器判断小于号<之前,存在依赖于模板参数的构造,才会出现这种问题。

3.模板的模板参数

template<typename T,
    typename <typename ELEM,
            typename ALLOC = std::allocator<ELEM>>
            class CONT = std::deque>
class Stack{
private:
    CONT<T> elems;
    ...
}

4.零初始化

对于int、double或者指针等基本类型,并不存在用一个有用的缺省值来对他们进行初始化的缺省构造函数,任何

未被初始化的局部变量都具有一个不确定的值

借助如下代码,我们可以确保对象已经执行了适当的缺省初始化,即使对内建类型对象也是如此
template <typename T>
void Foo()
{
    T x=T();
}

5.用字符串做为函数模板的实参

把字符串传给模板的引用参数会导致出人意料的结果,考虑下面的程序:

#include <string>

template <typename T>
inline T const& max(T const& a,T const& b)
{
    return a>b?b:a;
}

int main()
{
    std::string s;
    ::max("apple","peach");//ok,相同类型的实参
    ::max("apple","tomato");//error,不同的类型实参
}
解释:"apple"的类型为char const[6],"peach"的类型为char const[6],"tomato"的类型为char const[7]
-------------------------------------------------------
1.
成员函数模板不能被声明为虚函数,模板类的普通成员可以使虚函数
2.
模板实参的一个普遍约束是:在程序创建时,编译器或链接器要能够确定实参的值,如果实参的值等到运行时才能确定(譬如,局部变量的地址),就不符合模板是在程序创建时初始化的概念了
另一方面,有些常值不能作为有效地非类型实参,这些类型包括:空指针常量,浮点型值

posted on 2009-11-06 14:20  ATAK  阅读(299)  评论(0编辑  收藏  举报

导航