template<typename C> // const C& c 不需要加typename void f(const C& c){ // 嵌套从属类型名称,我们需要放置关键字typename // 为了告诉c++编译器C::const_iterator是个类型,缺省的话会被定为为非类型 typename C::const_iterator iter(c.begin()); // 太长的话也可以这么写 typedef typename C::const_iterator Iter; Iter iter(c.begin()); ... }
class Ta{ public: void show(const std::string& msg); ... }; class Tb{ public: void show(const std::string& msg); ... }; class Tc{ public: //没有show()函数 ... }; template<typename T> class MsgShow{ public: void doShow(const std::string& msg){ T t; t.show(msg); } }; //全特化版 template<> class MsgShow<Tc>{ public: ... }; template<typename T> class MsgShowMore : public MsgShow<T>{ public: void doShowMore(const std::string& msg){ doShow(msg); // 无法通过编译,因为此时编译器不知道T是个template参数,不知道是啥东西 } } //为了通过编译,我们要让编译器不进入模板基类观察行为 //1. template<typename T> class MsgShowMore : public MsgShow<T>{ public: void doShowMore(const std::string& msg){ this->doShow(msg); //通过编译 } } //2. template<typename T> class MsgShowMore : public MsgShow<T>{ public: using MsgShow<T>::doShow; void doShowMore(const std::string& msg){ doShow(msg); //通过编译 } } //3. template<typename T> class MsgShowMore : public MsgShow<T>{ public: void doShowMore(const std::string& msg){ MsgShow<T>::doShow(msg); //通过编译 } } //特化版本没有doShow() MsgShowMore<Tc> cmsg; std::string msg; ... cmsg.doShowMore(msa); //错误,因为Tc中没有doShow()函数
模板类与全特化:
//注意:无论是全特化还是偏特化,都必须有一个主模板 //调用优先级:全特化类>偏特化类>主版本模板类 // 主模板 // 模板函数 template<typename T, class C> bool f(T t, C c){ return (t > c); } // 模板类 template<typename T, class C> class F{ public: bool f(T t, C c){ return (t > c); } }; // 全特化 template<> bool f(int t, double c){ return (t > c); } template<> class F{ public: bool f(int t, double c){ return (t > c); } }; //偏特化 template<typename T> bool f(T t, double c){ return (t > c); } template<class C> class F{ public: bool f(int t, C c){ return (t > c); } }; //调用函数 int a = 1; double b = 2.0; f<int, double>(a, b); F<int, double>::f(a, b);
template<typename T, std::size_t s> class D { public: void area(s){ ... } }; // 当我们调用的时候,造成代码膨胀 D<double, 5> d1; D<double, 10> d2; d1.area(); d2.area(); //方法1. 共享同个基类,所以能共享同个show template<typename T> class B{ protected: void area(std::size_t s); }; template<typename T, std::size_t s> class D : private B<T>{ private: using B<T>::show; public: void area(){ this->area(s); //inline } }; // 方法2. 储存一个指针,指向数值所在内存 template<typename T> class B{ protected: B(std::size_t s, T* t) : size(s), data(t){} void setData(T* t) { data = t;} void area(){ ... } private: std::size_t size; T* data; }; template<typename T, std::size_t s> class D : private B<T>{ public: D() : B<T> (s, data) private: T data[s*s]; }; // 方法3. 将数据放进heap,通过new来分配内存 template<typename T> class B{ protected: B(std::size_t s, T* t) : size(s), data(t){} void setData(T* t) { data = t;} void area(){ ... } private: std::size_t size; T* data; }; template<typename T, std::size_t s> class D : private B<T>{ public: D() : B<T> (s, 0), data (new T[n*n]){ this->setData(data.get()); } private: boost::scoped_array<T> data; };