模板特殊化 (C++)

模板特殊化 (C++)

类模板可以部分专用化,生成的类仍是模板。 在类似于下面的情况下,部分专用化允许为特定类型部分自定义模板代码:

模板有多个类型,且只有一部分需要专用化。 结果是基于其余类型参数化的模板。

模板只有一个类型,但指针、引用、指向成员的指针或函数指针类型需要专用化。 专用化本身仍是指向或引用的类型上的模板。

示例:类模板的部分专用化

// partial_specialization_of_class_templates.cpp

#include

template struct PTS {

enum {

IsPointer = 0,

IsPointerToDataMember = 0

};

};

template struct PTS {

enum {

IsPointer = 1,

IsPointerToDataMember = 0

};

};

template struct PTS {

enum {

IsPointer = 0,

IsPointerToDataMember = 1

};

};

struct S{};

int main() {

printf_s("PTS::IsPointer == %d \nPTS::IsPointerToDataMember == %d\n",

PTS::IsPointer, PTS:: IsPointerToDataMember);

printf_s("PTS::IsPointer == %d \nPTS::IsPointerToDataMember == %d\n"

, PTS::IsPointer, PTS:: IsPointerToDataMember);

printf_s("PTS::IsPointer == %d \nPTS"

"::IsPointerToDataMember == %d\n",

PTS::IsPointer, PTS::

IsPointerToDataMember);

}

PTS::IsPointer == 0

PTS::IsPointerToDataMember == 0

PTS::IsPointer == 1

PTS::IsPointerToDataMember == 0

PTS::IsPointer == 0

PTS::IsPointerToDataMember == 1

示例:指针类型的部分专用化

如果有一个采用任何 T 类型的模板集合类,则可以创建采用任何指针类型 T* 的部分专用化。 以下代码演示了一个集合类模板 Bag 以及指针类型的部分专用化,在此专用化中,该集合在将指针类型复制到数组前取消引用它们。 该集合随后存储指向的值。 对于原始模板,只有指针本身将存储在集合中,从而使数据易受删除或修改。 在此特殊指针版本的集合中,添加了在 add 方法中检查 null 指针的代码。

// partial_specialization_of_class_templates2.cpp

// compile with: /EHsc

#include

using namespace std;

// Original template collection class.

template class Bag {

T* elem;

int size;

int max_size;

public:

Bag() : elem(0), size(0), max_size(1) {}

void add(T t) {

T* tmp;

if (size + 1 >= max_size) {

max_size *= 2;

tmp = new T [max_size];

for (int i = 0; i < size; i++)

tmp[i] = elem[i];

tmp[size++] = t;

delete[] elem;

elem = tmp;

}

else

elem[size++] = t;

}

void print() {

for (int i = 0; i < size; i++)

cout << elem[i] << " ";

cout << endl;

}

};

// Template partial specialization for pointer types.

// The collection has been modified to check for NULL

// and store types pointed to.

template class Bag {

T* elem;

int size;

int max_size;

public:

Bag() : elem(0), size(0), max_size(1) {}

void add(T* t) {

T* tmp;

if (t == NULL) { // Check for NULL

cout << "Null pointer!" << endl;

return;

}

if (size + 1 >= max_size) {

max_size *= 2;

tmp = new T [max_size];

for (int i = 0; i < size; i++)

tmp[i] = elem[i];

tmp[size++] = *t; // Dereference

delete[] elem;

elem = tmp;

}

else

elem[size++] = *t; // Dereference

}

void print() {

for (int i = 0; i < size; i++)

cout << elem[i] << " ";

cout << endl;

}

};

int main() {

Bag xi;

Bag xc;

Bag xp; // Uses partial specialization for pointer types.

xi.add(10);

xi.add(9);

xi.add(8);

xi.print();

xc.add('a');

xc.add('b');

xc.add('c');

xc.print();

int i = 3, j = 87, *p = new int[2];

*p = 8;

*(p + 1) = 100;

xp.add(&i);

xp.add(&j);

xp.add(p);

xp.add(p + 1);

delete[] p;

p = NULL;

xp.add(p);

xp.print();

}

10 9 8

a b c

Null pointer!

3 87 8 100

示例:定义部分专用化,使一种类型为 int

以下示例定义了一个采用由任意两种类型构成的对的模板类,然后定义已专用化的模板类的部分专用化,使其中一个类型为 int。 该专用化定义了基于整数实现简单气泡排序的另一种排序方法。

// partial_specialization_of_class_templates3.cpp

// compile with: /EHsc

#include

using namespace std;

template class Dictionary {

Key* keys;

Value* values;

int size;

int max_size;

public:

Dictionary(int initial_size) : size(0) {

max_size = 1;

while (initial_size >= max_size)

max_size *= 2;

keys = new Key[max_size];

values = new Value[max_size];

}

void add(Key key, Value value) {

Key* tmpKey;

Value* tmpVal;

if (size + 1 >= max_size) {

max_size *= 2;

tmpKey = new Key [max_size];

tmpVal = new Value [max_size];

for (int i = 0; i < size; i++) {

tmpKey[i] = keys[i];

tmpVal[i] = values[i];

}

tmpKey[size] = key;

tmpVal[size] = value;

delete[] keys;

delete[] values;

keys = tmpKey;

values = tmpVal;

}

else {

keys[size] = key;

values[size] = value;

}

size++;

}

void print() {

for (int i = 0; i < size; i++)

cout << "{" << keys[i] << ", " << values[i] << "}" << endl;

}

};

// Template partial specialization: Key is specified to be int.

template class Dictionary {

int* keys;

Value* values;

int size;

int max_size;

public:

Dictionary(int initial_size) : size(0) {

max_size = 1;

while (initial_size >= max_size)

max_size *= 2;

keys = new int[max_size];

values = new Value[max_size];

}

void add(int key, Value value) {

int* tmpKey;

Value* tmpVal;

if (size + 1 >= max_size) {

max_size *= 2;

tmpKey = new int [max_size];

tmpVal = new Value [max_size];

for (int i = 0; i < size; i++) {

tmpKey[i] = keys[i];

tmpVal[i] = values[i];

}

tmpKey[size] = key;

tmpVal[size] = value;

delete[] keys;

delete[] values;

keys = tmpKey;

values = tmpVal;

}

else {

keys[size] = key;

values[size] = value;

}

size++;

}

void sort() {

// Sort method is defined.

int smallest = 0;

for (int i = 0; i < size - 1; i++) {

for (int j = i; j < size; j++) {

if (keys[j] < keys[smallest])

smallest = j;

}

swap(keys[i], keys[smallest]);

swap(values[i], values[smallest]);

}

}

void print() {

for (int i = 0; i < size; i++)

cout << "{" << keys[i] << ", " << values[i] << "}" << endl;

}

};

int main() {

Dictionary dict(10);

dict.print();

dict.add("apple", "fruit");

dict.add("banana", "fruit");

dict.add("dog", "animal");

dict.print();

Dictionary dict_specialized(10);

dict_specialized.print();

dict_specialized.add(100, "apple");

dict_specialized.add(101, "banana");

dict_specialized.add(103, "dog");

dict_specialized.add(89, "cat");

dict_specialized.print();

dict_specialized.sort();

cout << endl << "Sorted list:" << endl;

dict_specialized.print();

}

{apple, fruit}

{banana, fruit}

{dog, animal}

{100, apple}

{101, banana}

{103, dog}

{89, cat}

Sorted list:

{89, cat}

{100, apple}

{101, banana}

{103, dog}

相关推荐

打印机如何开机

打印机如何开机

📅 10-15 👁️ 8427
梦幻西游苦行脚本

梦幻西游苦行脚本

📅 09-22 👁️ 751
初学者的Struts教程

初学者的Struts教程

📅 11-03 👁️ 1727
三点水加一个益是什么字

三点水加一个益是什么字

📅 09-20 👁️ 9316
佳能中国

佳能中国

📅 10-03 👁️ 4567