c++ 模板 指標型別偏特化

2022-11-01 18:01:59

一步步來,先簡單點.
目標:我們要實現一個模板類,例化後,可以通過get_val獲取到值,通過get_ptr獲取到指標.具體什麼意思結合例子來看看吧.
例子:

struct A{
    int data;
    A(int _data = 0):data(_data){}
};
template <typename T>
 class heap_node{
 public:
 	 typedef T  val_type;
	 typedef T* ptr_type;
	 typedef T& ref_type;
	 ptr_type data;
	 ref_type get_val() { return *data; }
	 ptr_type get_ptr() { return data; }
	 heap_node(ptr_type d) :data(d){
		 printf("<T> (T*)\n");
	 }
	 heap_node(ref_type d) :data(&d){
		 printf("<T> (T)\n");
	 }
 };

 int main() {
	 A a(10);
	 printf("ptr=%p\n",&a);
	 heap_node<A> p0(a);
	 printf("ptr=%p val=%d\n", p0.get_ptr(),p0.get_val().data);
	 heap_node<A> p1(&a);
	 printf("ptr=%p val=%d\n", p1.get_ptr(), p1.get_val().data);
	/*
	 heap_node<A*> p2(a);
	 printf("ptr=%p val=%d\n", p2.get_ptr(), p2.get_val().data);
	 heap_node<A*> p3(&a);
	 printf("ptr=%p val=%d\n", p3.get_ptr(), p3.get_val().data);
	*/
     char ch = getchar();
}
 

(不要在類裡直接儲存值型別的資料,可以用指標或者參照都可以)
發現heap_node<A> p2(a)或者heap_node<A> p3(&a)的時候,無法正常表達我們原來的意識,此時的val_type就變成指標型別,怎麼解決呢.需要對<T*>特殊處理一下.

struct A{
    int data;
    A(int _data = 0):data(_data){}
};
template <typename T>
 class heap_node{
 public:
 	 typedef T  val_type;
	 typedef T* ptr_type;
	 typedef T& ref_type;
	 ptr_type data;
	 ref_type get_val() { return *data; }
	 ptr_type get_ptr() { return data; }
	 heap_node(ptr_type d) :data(d){
		 printf("<T> (T*)\n");
	 }
	 heap_node(ref_type d) :data(&d){
		 printf("<T> (T)\n");
	 }
 };
//<T*>偏特化
template <typename T>
 class heap_node<T*>{
 public:
 	 typedef T  val_type;
	 typedef T* ptr_type;
	 typedef T& ref_type;
	 ptr_type data;
	 ref_type get_val() { return *data; }
	 ptr_type get_ptr() { return data; }
	 heap_node(ptr_type d) :data(d){
		 printf("<T*> (T*)\n");
	 }
	 heap_node(ref_type d) :data(&d){
		 printf("<T*> (T)\n");
	 }
 };
 int main() {
	 A a(10);
	 printf("ptr=%p\n",&a);
	 heap_node<A> p0(a);
	 printf("ptr=%p val=%d\n", p0.get_ptr(),p0.get_val().data);
	 heap_node<A> p1(&a);
	 printf("ptr=%p val=%d\n", p1.get_ptr(), p1.get_val().data);
	
	 heap_node<A*> p2(a);
	 printf("ptr=%p val=%d\n", p2.get_ptr(), p2.get_val().data);
	 heap_node<A*> p3(&a);
	 printf("ptr=%p val=%d\n", p3.get_ptr(), p3.get_val().data);
	
     char ch = getchar();
}

可能還有const修飾T,或者範例化T為原始資料型別......,都可能出現類似的問題,可以用偏特化解決.這裡就不一一列舉出來哈.
我們可以發現,特例化的<T*>模板與原模板程式碼上幾乎一樣的,是不是可以優化一下呢.
直接上程式碼:

struct A{
    int data;
    A(int _data = 0):data(_data){}
};

template <class T>
 struct heap_node_type{
	 typedef T  val_type;
	 typedef T* ptr_type;
	 typedef T& ref_type;
 };

 template <class T>
 struct heap_node_type<T*>{
	 typedef T  val_type;
	 typedef T* ptr_type;
	 typedef T& ref_type;
 };

 template <class T>
 class heap_node :heap_node_type<T>{
 public:
	 ptr_type data;
	 ref_type get_val() { return *data; }
	 ptr_type get_ptr() { return data; }
	 heap_node(ptr_type d) :data(d){
		 printf("<T> (T*)\n");
	 }
	 heap_node(ref_type d) :data(&d){
		 printf("<T> (T)\n");
	 }
 };
 
 int main() {
	 A a(10);
	 printf("ptr=%p\n",&a);
	 heap_node<A> p0(a);
	 printf("ptr=%p val=%d\n", p0.get_ptr(),p0.get_val().data);
	 heap_node<A> p1(&a);
	 printf("ptr=%p val=%d\n", p1.get_ptr(), p1.get_val().data);

	 heap_node<A*> p2(a);
	 printf("ptr=%p val=%d\n", p2.get_ptr(), p2.get_val().data);
	 heap_node<A*> p3(&a);
	 printf("ptr=%p val=%d\n", p3.get_ptr(), p3.get_val().data);

	 int b = 100;
	 printf("==========int====\nptr=%p\n", &b);
	 heap_node<int> p4(b);
	 printf("ptr=%p val=%d\n", p4.get_ptr(), p4.get_val());
	 heap_node<int> p5(&b);
	 printf("ptr=%p val=%d\n", p5.get_ptr(), p5.get_val());

	 heap_node<int*> p6(b);
	 printf("ptr=%p val=%d\n", p6.get_ptr(), p6.get_val());
	 heap_node<int*> p7(&b);
	 printf("ptr=%p val=%d\n", p7.get_ptr(), p7.get_val());

	 string str = "string";
	 printf("==========str====\nptr=%p %s\n", &str,str);
	 heap_node<string> s4(str);
	 printf("ptr=%p val=%s\n", s4.get_ptr(), s4.get_val());
	 heap_node<string> s5(&str);
	 printf("ptr=%p val=%s\n", s5.get_ptr(), s5.get_val());

	 heap_node<string*> s6(str);
	 printf("ptr=%p val=%s\n", s6.get_ptr(), s6.get_val());
	 heap_node<string*> s7(&str);
	 printf("ptr=%p val=%s\n", s7.get_ptr(), s7.get_val());

	 const int c = 123;
	 printf("==========const int====\nptr=%p\n", &c);
	 heap_node<const int> c4(c);
	 printf("ptr=%p val=%d\n", c4.get_ptr(), c4.get_val());
	 heap_node<const int> c5(&c);
	 printf("ptr=%p val=%d\n", c5.get_ptr(), c5.get_val());

	 heap_node<const int*> c6(c);
	 printf("ptr=%p val=%d\n", c6.get_ptr(), c6.get_val());
	 heap_node<const int*> c7(&c);
	 printf("ptr=%p val=%d\n", c7.get_ptr(), c7.get_val());
     char ch = getchar();
}