类模板 及其 特化

(1)

// -------------类模板 体验--------------------
template <typename T1, typename T2>
class Test //原始的类模板后 加上class Test<T1, T2>会报错
{
public:
void add(T1 a, T1 b)
{
cout << "void add(T1 a, T1 b)" << endl;
cout << "a + b = " << a+b << endl;
}
};

template <typename T1, typename T2>
class Test<T1*, T2*> // class Test<T1, T2>报错 。但是class Test<T1*, T2*>不会报错
{
public:
void add(T1* a, T2* b)
{
cout << "void add(T1*a, T2* b)" << endl;
cout << "*a + *b = " << *a + *b << endl;
}
};

//template <typename T, typename T_again> 这是不被编译器允许的。泛指类型T_again没有被使用,会引起编译报错。
template <typename T>
class Test<T, T>
{
public:
void add(T a, T b)
{
cout << "void add(T a, T b) "<< endl;
cout << "a + b = " << a+b << endl;
}
};
/* 这个模板类和上面的这个本质是同一个模板类。
template <typename T2>
class Test<T2, T2>
{
public:
void add(T2 a, T2 b)
{
cout << "void add(T a, T b) "<< endl;
cout << "a + b = " << a+b << endl;
}
};
*/

template < > // 没有泛指类型,是完全特化
class Test < void*, void* > // 当 T1 == void* 并且 T2 == void* 时
{
public:
void add(void* a, void* b)
{
cout << "void add(void* a, void* b)" << endl;
cout << "Error to add void* param..." << endl;
}
};

class myClass{
}; // 编译器默认提供的构造函数是公有的。

int main(void)
{
int x = 12;
unsigned int y = 13;

Test<int ,int> a;
a.add(3, 6);

Test<int*, unsigned int*> b;
b.add(&x, &y);

Test < void*, void* > c;
c.add((void*)&x, (void*)&y);

myClass mytest;

return 0;
}

(2)
//-------  模板类的特化 -------------------------------------

template
<typename T1, typename T2, typename T3>
class Test{
public:
T3 get_add(T1 a, T2 b)
{
T3 tmp = a+b;
cout<< "原始的 类模板 Test: get_add = "<< tmp << endl;

return tmp;
}
};

template
<typename T1, typename T2>
//class Test<T1, T2>{ // ????? 编译报错 原因: 既然命名为Test,
// 那么编译器肯定认为这是上面那个类的特化实现,所以报错 缺少参数(上面那个类是三个参数的哦)
class Test2{ // 把这里改为Test2以后,编译器认为这个类和上面的Test类没有关系了,这是一个新的类模板,自然也不会报错缺少参数之类的了。
public:
void get_add(T1 a, T2 b)
{
cout<< "这是重新定义了一个新的类模板哦!不是特化!" endl;
}
};

template
<typename T1, typename T2>
class Test<T1, T2, int>{ //由于只指定了一部分参数,剩下的未指定的需在参数列表中,否则编译会报错。
//class Test2{
public:
int get_add(T1 a, T2 b)
{
int tmp = a + b;
cout<< "部分特化的类模板 Test: get_add = "<< a+b << endl;
return tmp;
}
};

template<>
//class Test<void*, void*, int>{ // ******* 喜发现,如果这里是void*,那么下面传入int*,即定义Test<int*,int*,int> obj_3;,并不能顺利匹配,会引起编译报错。
class Test<int*, int*, int>{
public:
int get_add(int* p1, int*p2) // main函数内调用该类对象的该成员函数进行二次编译的时候,
{ // 报错 class Test<T1, T2, int>的该部分特化的类模板的成员函数不能进行两个指针的相加。
int tmp = static_cast<int>( *(int*)p1 + *(int*)p2 ); // 所以我在想,难道同一个类模板的部分特化的优先级高于完全特化? 实测NO
cout<< "完全特化的类模板 " ; // 编译器按照部分特化的类的规则,去对我写的完全特化的类,进行编译检查了
// 如果这里是void* 去匹配传入int*, 是有问题的。因为这俩不是同一个类型啊!  所以说,特化遵循严格的类型匹配!
return tmp; // 我们平常习惯了默认提供的的隐式类型转换,这是个毛病。void*和int*不是同一个类型。
}
};

template<>
class Test<int, int, int>{
public:
int get_add(int a, int b)
{
int tmp = a + b;
cout<< "3个int的 完全特化的类模板 Test: get_add = "<< a+b << endl;
return tmp;
}
};

int main()
{
// 范型之--- 类模板 部分特化 完全特化 实验

// int 同类型相加
Test<int, int, int> obj;
int result = obj.get_add(2, 3);
cout << "result = "<< result << endl<< endl;

// float 同类型相加
Test<float, float, float> obj_1;
float result_1 = obj_1.get_add(2.333, 3.3);
cout << "result_1 = "<< result_1 << endl<< endl;

// int float 混合类型相加
Test<int, float, float> obj_2;
float result_2 = obj_2.get_add(2.333, 3.4);
cout << "result_2 = "<< result_2 << endl<< endl;

// 指针类型相加
Test<int*,int*,int> obj_3;

int x1=22; int x2 = 33;
int result_3 = obj_3.get_add(&x1, &x2);

cout << "result_3 = "<< result_3 << endl;

return 0;
}
// 类名很重要,是不是同一个类模板,要看是不是同一个类名。
// 类模板有特化,同一个类模板的类之间,类名肯定都是一样的。
// 类模板的成员函数的实参到形参的传递,int*到void*需要手动去显式转换才ok。 实测是如此。
// int 和 double之类的隐式转换也是类似的。
// 一般的我们认为void*兼容int*之类的。
// 可是在类模板的这个实验里,体现出了的确存在类型不同的问题。
// 用习惯了编译器平时的隐式转换咯!是个毛病。

(3)

// --------------------------函数模板 : 函数模板只有完全特化----------------------------------
template < typename T >
bool Equal(T a, T b)
{
cout << "bool Equal(T a, T b)" << endl;

return a == b;
}

// 上述函数模板的一种特化实现
template <>
bool Equal(int a, int b)
{
cout << "bool Equal(int a, int b)"<< endl;
return a == b;
}

/* 突发奇想? 想写个函数模板的部分特化?哈哈,想一想,在main函数内该如何定义生成使用这部分特化的函数模板呢?
template <typename T, char b>
bool Equal(int a, int b)
{
cout << "函数模板部分特化"<< endl; // 函数模板的特化,只有完全特化!
return a == b;
}
*/

int main()
{
cout << Equal( 1, 1 ) << endl;
cout << Equal( 0.001, 0.001 ) << endl;

return 0;
}

原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/10473688.html

时间: 2024-10-13 14:43:30

类模板 及其 特化的相关文章

C++—模板(2)类模板与其特化

我们以顺序表为例来说明,普通顺序表的定义如下: 1 typedef int DataType; 2 //typedef char DataType; 3 class SeqList 4 { 5 private : 6 DataType* _data ; 7 int _size ; 8 int _capacity ; 9 } ; 模板类也是模板, 必须以 关键字templ ate开头, 后接模板形参表. 模板类一般格式如下:template<class 形参名 1, class 形参名 2, .

类模板使用示例(二)类模板整体特化

特化的目的: 表明该模板在特殊类型下具有不同的行为. 注意:特化的实现可以和基本类模板的实现完全不同. Stack2.h代码: #ifndef STACK2_H #define STACK2_H #include <deque> #include <string> #include <stdexcept> #include "TestCC.h" template<> class Stack<std::string> { pub

类模板使用示例(三) 类模板局部特化

MyClass.h文件代码: #ifndef MYCLASS_H #define MYCLASS_H #include<iostream> template <typename T1, typename T2> class MyClass { public: void print() { std::cout << "T1 VS. T2" << std::endl; } }; template <typename T> clas

类模板特化

主类模板Stack,使用vector构建,实现栈的功能. template <typename T> class Stack { private: std::vector<T> elems; public: void push(T const &elem){ elems.push_back(elem); } void pop(){ if(elems.empty()) return; elems.pop_back(); } T top() const{ if(elems.em

C++类模板

在上篇文章(C++函数模板)中,主要介绍了C++中函数模板,与函数相似,类也可以被一种或多种类型参数化.容器类就是一个具有这种特性的典型的例子, 本文地址:http://www.cnblogs.com/archimedes/p/cpp-class-template.html,转载请注明源地址. 以下通过设计一个类模板Stack的实现来说明: 类模板Stack的实现 #include<iostream> #include<vector> #include<stdexcept&g

类模板和函数模板

函数模板: 函数模板全特化:所谓特化,是指相对普通模板的特化,是另外一个模板.但不是实例,只是模板 template <class T>                                      //普通函数模板,泛型T mymax(const T t1, const T t2){   return t1 < t2 ? t2 : t1;} template <>const char* mymax(const char* t1,const char* t2)  

[转]C++中模板的特化与偏特化

转载自:http://hi.baidu.com/klcdyx2008/blog/item/5adbf77b79f316f90bd1873c.html 1.引言C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现.目前,STL在C++社区中得到了广泛的关注.应用和研究.理解和掌握模板是学习.应用和研究以及扩充STL的基础.而STL模板实例中又充斥着大量的模板特化和偏特化. 2.模板的定义(1) 类模板定义一个栈的类模板,

c++类模板深度剖析

1.类模板的泛指类型可以定义多个 template <typename T1, typename T2> class Test { public: void add(T1 a, T2, b); }; 使用时: Test<int, float> t1; //T1的泛指类型就是int, T2的泛指类型就是float. 2.类模板的特化类型 (1)意思就是如果定义了一个类模板,这个类模板的参数有多个,但是如果当使用这个类模板的时候,我们传递参数时,参数的类型是一样的话,编译器就会将类模板

c++数组类模板的实现

1.预备知识 (1)模板参数不仅仅可以是类型参数,还可以是数值型参数. 如: template <typename T, int N>//int N就是数值型参数, 要注意这个int类型,因为这里要注意数值型参数的限制,下面有说数值型参数的限制. void func() { T a[N];//使用模板参数来定义局部数组,模板的数值型参数来表示数组的大小. } func<double, 10>();//这样进行使用,数值型参数,也就是第二个参数要是常量,因为这是数值型模板参数的限制造