C++ Template之技巧性基础知识
1.对于T是自定义类型的,如果存在子类型则需要在模版内部加上typename
示例代码:
template<typename T> class Myclass { typename T::SubType *ptr;//需要加上typename不然编译器可能误解为是静态对象SubType和ptr相乘 };
2.类模版里对基类成员函数的调用使用BASE::exit();和this->,避免调用的是外部全局函数,但是在vc6.0上面这条规则是先调用的BASE里面的函数。
示例代码:
#include <iostream> #include <string> #include <vector> using namespace std; void exit() { cout << "hello world" <<endl; } template <typename T> class BaseMyclass { public: void exit() { cout << "Base" <<endl; } }; template <typename T> class Myclass:public BaseMyclass<T> { public: void foo() { exit(); } }; int main() { Myclass<int> m1; m1.foo(); return 0; }
3.成员模板,由于两种不同的类型之间的赋值不能使用类本身的接口,所以需要重新设计接口。
示例代码:
#include <iostream> #include <string> #include <vector> using namespace std; template <typename T> class Stack { public: template <typename T2> Stack<T>& operator=(Stack<T2> const &); }; template <typename T> template <typename T2> Stack<T>& Stack<T>::operator=(Stack<T2> const &op2) { } int main() { return 0; }
调用时首先通过显式指定的模板类型实例化一个类,然后通过实例化一个成员函数,只是现在的成员函数是模板函数,然后根据调用的参数实例化成一个成员函数。
4.模板的模板参数,实际上是一个模板类,上面的成员模板实际上是一个模板函数。
代码示例:
template <typename T,template<typename T> class CONT = vector> class Stack { public: };
5.零初始化,因为模板不知道类型所以我们无法用任何一个常量来初始化模板参数定义的变量。但是可以如下例子进行初始化
代码示例:
#include <iostream> #include <string> #include <vector> using namespace std; template <typename T> void foo() { T x = T(); } template <typename T> class Myclass { private: T x; public: Myclass():x(T()){} }; int main() { foo<int>(); Myclass<int> m1; return 0; }
6.使用字符串作为函数模板的实参若是引用则需要字符串长度完全匹配
示例代码:
template <typename T> inline T& const max(T const& a,T const& b) { return a > b ? a:b; } int main() { cout << max("apple","peach")<<endl;//OK cout << max("apple","tomato")<<endl;//ERROR return 0; }
若不为引用则不需要字符串长度完全一样,原因是参数会转换成字符串指针类型,属于相同的类型
示例代码:
#include <iostream> #include <string> #include <vector> using namespace std; template <typename T> inline T max(T a,T b) { return a > b ? a:b; } int main() { cout << max("apple","peach")<<endl;//OK cout << max("apple","tomato")<<endl;//OK return 0; }
字符串作为实参的测试示例:
template <typename T> void ref(T const& x,T const& y) { cout << "x int the ref is " << typeid(x).name() <<endl; } template <typename T> void nonref(T x) { cout << "x int the noref is " << typeid(x).name() <<endl; } int main() { ref("hello"); nonref("hello"); return 0; }
一切源于对计算机的热爱