博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[c++][template]类模板

Posted on 2010-05-10 21:10  xuczhang  阅读(1163)  评论(0编辑  收藏  举报

 

1. 在类模板中使用类型时要加上模板类型,如:Stack<T>。而表示类时就只用类名,如:Stack。

2. 一个绝对异常安全并且返回被删除元素的pop()是不可能的。参考[CargillExceptionSafty]

3. 对于类模板,成员函数只有在被使用的时候才会被实例化。如果类模板中含有静态成员,那么用来实例化的每种类型,都会实例化这些静态成员。

4. 特化类模板

template<>
class Stack<std::string>
{
public:
    void push(std::string const& elem);
    void pop();
    std::string top() const;
    bool empty() const;
private:
    //Stack(Stack<T> const&);
    Stack<std::string>& operator=(Stack<std::string> const&);
private:
    std::vector<std::string> m_elems;
};
 
void Stack<std::string>::push(const std::string &elem)
{
    m_elems.push_back(elem);
}

5. 局部特化

template <typename T1, typename T2>
class MyClass {
  ...
};

可以局部特例化为以下几种类型:

template <typename T>
class MyClass<T,T> {
  ...
};
 
template <typename T>
class MyClass<T,int> {
  ...
};
 
template <typename T1, typename T2>
class MyClass<T1*,T2*> {
  ...
};

同等匹配问题:

比如:

Myclass<int,int> m; //equally suitable to MyClass<T,T> and MyClass<T,int>
MyClass<int*,int*> m; //equally suitable to MyClass<T,T> and MyClass<T1*,T2*>

解决上述二义性的方法就是提供一个完全匹配的类型的特化,比如提供一个相同类型的指针的特化:

template <typename T>
class MyClass<T*,T*> {
  ...
};

 

6. 缺省模板参数

下面的例子就将CONT的默认值设置为std::vector<T>

template<typename T, typename CONT = std::vector<T> >
class Stack {
    private:
        CONT elems;
 
};

7. 非类型的类模板参数

template<typename T, int MAXSIZE>
class Stack {
    private:
        T elems[MAXSIZE];
    ...
};

非类型模板参数的限制:通常它们可以是常整数(包括枚举值)或者指向外部链接对象的指针。

浮点数和类对象是不允许作为非类型模板参数的

template <char const* name> 
class MyClass { 
}; 
 
MyClass<"hello"> x;   // ERROR: string literal "hello" not allowed 
 
//You cannot use a global pointer either:
template <char const* name> 
class MyClass { 
}; 
 
char const* s = "hello"; 
 
MyClass<s> x;         // ERROR: s is pointer to object with internal linkage 
 
//However, the following is possible:
template <char const* name> 
class MyClass { 
}; 
 
extern char const s[] = "hello"; 
 
MyClass<s> x;        // OK