1.双重模版参数,即模版的参数也是模版,不过只能用于类模版,函数模版中不能这么使用
例如 template <typname T, template<typename E,typename ALLOC=std::allocator<E>>class CONT=std::deque>
stack8{}...
这里注意首先 class CONT不能写typename CONT ,这个比较好理解,这是个类模版。
其次给CONT设置默认值=std::deque,由于deque的模板参数是2个,尽管第二个有默认值,但是在这里会忽略,进行严格匹配,所以如果默认值给的deque
则template class CONT必须有两个模版参数
2.类模板的成员函数也可以是函数模版
template<typename T2,template<typename elem2,typename alloc2=std::allocator<elem2>>class CONT2>
stack8<T1,CONT>&operator=(stack8<T2,CONT2>const&);
不过这里的CONT2不能有默认值,函数模板的默认值好像是到c++11才支持的。
后面写的时候也发现了点问题,原来在类外进行函数定义时,不能把模板的默认参数带上....
比如下面的std::deque必须去掉...
template<typename T1,template<typename elem,typename alloc=std::allocator<elem>>class CONT=std::deque>
void stack<T1,CONT>::pop()
{
elems.pop_front();
}
不过有点奇怪的是,一般类外定义成员函数,如果函数声明时有默认参数,类外定义的函数是不能添加默认参数的。
但是放到模板里就又没问题了。比如pop(int m=4)编译也可以过啊?
3. 一个简单的template<typename T> T const& max(T const&a, T const &b){return a>b?a:b;}
如果调用
max("123","abc"); ok
max("123","abcd"); complier error
为什么?
对于第二种 错误提示是 T的类型是const char [4] 还是const char [5]?
这里又解释了一点,如果参数推导时,形参是引用,数组作为参数传入时,不会退化为指针,所以这里识别的是const char[]这种数组类型!!!
改成 T max(T a, T b){return a>b?a:b;}就可以了
1 #include<deque> 2 #include<memory> 3 #include<string> 4 #include<iostream> 5 6 using namespace std; 7 8 template<typename T1,template<typename elem,typename alloc=std::allocator<elem>>class CONT=std::deque> 9 class stack 10 { 11 private: 12 CONT<T1> elems; 13 int m; 14 public: 15 void push(T1 const&); 16 void pop(int m=4); 17 T1 top(); 18 bool empty()const; 19 20 stack<T1,CONT>():m(){} 21 22 template<typename T2,template<typename elem2,typename alloc2=std::allocator<elem2>>class CONT2> 23 stack<T1,CONT>&operator=(stack<T2,CONT2>const&); 24 25 }; 26 template<typename T1,template<typename elem,typename alloc>class CONT> 27 void stack<T1,CONT>::push(T1 const& t) 28 { 29 elems.push_front(t); 30 } 31 32 template<typename T1,template<typename elem,typename alloc=std::allocator<elem>>class CONT> 33 void stack<T1,CONT>::pop(int m=4) 34 { 35 elems.pop_front(); 36 } 37 template<typename T1,template<typename elem,typename alloc=std::allocator<elem>>class CONT> 38 T1 stack<T1,CONT>::top() 39 { 40 return elems.front(); 41 } 42 43 template<typename T1,template<typename elem,typename alloc=std::allocator<elem>>class CONT> 44 bool stack<T1,CONT>::empty()const 45 { 46 return elems.empty(); 47 } 48 template<typename T1,template<typename elem,typename alloc=std::allocator<elem>>class CONT> 49 template<typename T2,template<typename elem2, typename alloc2=std::allocator<elem>>class CONT2> 50 stack<T1,CONT>& stack<T1,CONT>::operator =(const stack<T2,CONT2>& stack2) 51 { 52 if((void*)this==(void*)&stack2) 53 { 54 return *this; 55 } 56 else 57 { 58 stack<T2,CONT2>tp(stack2); 59 while(!tp.empty()) 60 { 61 this->push(tp.top()); 62 tp.pop(); 63 } 64 return *this; 65 } 66 }; 67 68 69 class String 70 { 71 public: 72 String(char*buf):m_str(buf) 73 { 74 cout<<"constructor called"<<endl; 75 } 76 void set_m_str(char* buf=NULL); 77 private: 78 string m_str; 79 }; 80 81 void String::set_m_str(char* buf) 82 { 83 ; 84 } 85 void func(String& str) 86 { 87 88 } 89 90 template <typename T> 91 inline T max (T a, T b) 92 { 93 return a>b?a:b; 94 } 95 int main() 96 { 97 stack<int> ints; 98 stack<float>floats; 99 100 ints.push(1); 101 ints.push(2); 102 floats=ints; 103 104 ::max("asda","123"); 105 }