`

c++ - template specialization and partial specialization

    博客分类:
  • c++
c++ 
阅读更多

in this post, we are going to examining partialization.

 

There are two kind of partialization, one is full specialization, and the other is partial specialization.

 

  • full specialization
  • partial specialization

 

 

 

Full specialization

 

 

class

 

  •      QueueItem
  •      Queue

 

Are used for full specialization, by full specialization, it means once specialized, there exist only one instance for the specialized template arguments.

 

 

see the code below. 

 

 

/**
* file
*  template_specialization.h
* description:
*   template specialization and partial specialization
*/


#include <iostream>
#include <string>
#include <assert.h>
#include <cassert>

using std::string;
using std::ostream;
using std::istream;
using std::cerr;
using std::cout;
using std::endl;
using std::exit;

/**
*
*  class
*     QueueItem
*     Queue
*  are used for full specialization, by full specialization, it means once specialized, there exist only one instance for the specialized template arguments.
* 
* Later we will discuss  parital specialization
*/

template<class Type>
class QueueItem
{
public:
	QueueItem(const Type &val) : next(0), value (val)  {} 

	QueueItem<Type> *next;
	Type value;
protected:
};


template <class Type>
class Queue 
{
public:
	Queue() : front(0), back (0) {} 
	~Queue() ;
	Type remove();
	Type min();
	Type max();

	void add(const Type &);
	bool is_empty() const {
		return front == 0;
	}

	// class member template
	// with this you can define 
	// things like Queue<int>::CL<string> ...
	// which may sound useless at the frist glance, but we will see
	template <class T>
	class CL
	{
		T name;
		Type mem;
	};

	template <class Iter>
	void assign(Iter first, Iter last)
	{
		while (!is_empty()) 
			remove(); // call Queue<T>::remove
		for (; first != last; ++first) 
			add(*first);
	}

private:
	QueueItem<Type> *front;
	QueueItem<Type> *back;
protected:
};

class LongDouble 
{
public:
	LongDouble(double dval) : value(dval) {}
	bool compareLess(const LongDouble & rhs) { return value < rhs.value;  }
private:
	double value;
protected:
};

template <class Type>
Queue<Type>::~Queue()
{
	while (!is_empty()) {
		remove();
	}
}

template <class Type>
void Queue<Type>::add(const Type &val)
{

	QueueItem<Type> *pt = new QueueItem<Type>(val);
	if (is_empty())
	{
		front = back = pt;
	}
	else 
	{
		back->next = pt;
	}
	
}


template <class Type>
Type Queue<Type>::remove()
{
	if (is_empty()) {
		cerr << "remove() on empty queue\n";
		exit(-1);
	}
	QueueItem<Type> *pt = front;
	front = front->next;
	Type retval =  pt->value;
	delete pt;
	return retval;
}


// find minimum value in the queue
template <class Type>
Type Queue<Type>::min()
{
	assert(! is_empty());
	Type min_value = front->value;
	for (QueueItem<Type> * pq = front->next; pq != 0; pq = pq->next)
	{
		if (pq->value < min_val)
			min_val = pq->value;
	}
	return min_val;
}

template <class Type>
Type Queue<Type>::max()
{
	assert(! is_empty());
	Type max_val = front->value;
	for (QueueItem<Type> * pq = front->next; pq != 0; pq = pq->next)
	{
		if (pq->value > max_val);
			max_val = pq->value;
	}
	return max_val;
}


/**
* template<>
*   LongDouble Queue<LongDouble>::min()
* 
* this is the specialization of member
* which once is defind, will create a specialization on the class of template<> class Queue<LongDouble>;
* 
* also, if the specialization will totally redefine the data members, not just the member functions, you can try the 
* full specialization on class as well.
*  
*  template<>
*  class <void *> Queue{ };
*
* you cannot do 
*   specialization member 
*   specialization on the class
* at the same time
*
* this is full specialization, while you can do partial specialization, please refer the partial specialization later on this chapter
*/
template <>
LongDouble Queue<LongDouble>::min() 
{
	assert(! is_empty());
	LongDouble min_val = front->value;
	for (QueueItem<LongDouble> * pq = front->next; pq != 0; pq = pq->next)
	{
		if (pq->value.compareLess(min_val))
			min_val = pq->value;
	}
	return min_val;
}


/**
* template<>
*   LongDouble Queue<LongDouble>::min()
* 
*/
template <>
LongDouble Queue<LongDouble>::max()
{
	assert(! is_empty());
	LongDouble max_val = front->value;
	for (QueueItem<LongDouble> * pq = front->next; pq != 0; pq = pq->next)
	{
		if (!pq->value.compareLess(max_val))
			max_val = pq->value;
	}
	return max_val;
}

 

 

As we have described in the code above, you can do template specialization on the data member, you can also do specialization on the the template class itself. as below.

 

 

template<>
class Queue<void *>
{
public:
	Queue() : front(0), back (0) {} 
	~Queue() ;
	void* remove();
	void* min();
	void* max();

private:
	QueueItem<void *> *front;
	QueueItem<void *> *back;
protected:

};
 

 

while, let me restate/reiterate/rephraze/recapitulate the that 

you cannot do 

 

  1. specialization on member function 
  2. specialization on class template

 

at the same time. 

 

partial specialization

unlike the full specialization, which will have only one template instance for the particular specialized type parameter. while, partial specialization results in another template, which has infinite set of instances.

 

let's see an example. 

 

 

/**
*
*  class
*     Screen
*  are used for partial specialization, by partial which means after the specialization, there still exist inifinite set of template instances based on the unspecialized type parameter.
*/

template<int hi, int wid>
class Screen
{
	//...
};

/**
* fixed (specialized) the wid non-type template parameter to 80, if the template class has type template parameter, we can fixed the 
*/
template<int hi>
class Screen<hi, 80>
{
public:
	Screen();
private:
	string _screen;
	string::size_type _cursor;
	short _height;
//	 use the special 
};

/**
* template<int hi>
* Screen<hi, 80>::Screen()
*
*/
template<int hi>
Screen<hi, 80>::Screen() : _screen(""), _cursor(string("").size), _height(80)
{
}
 

 

 

while the above code shows partial specialization on the type parameters. let's seen the example. 

 

 

/*
* template<class T1, class T2>
* class Foo {}
* 
* shows how to do partial specialization on type parameter template class.
*/
template<class T1, class T2>
class Foo
{
};

template<class T1>
class Foo<T1, string>
{
};
 

 

 

 

分享到:
评论

相关推荐

    Modern C++ Design Generic Programming and Design Patterns Applied.pdf

    Partial template specialization Typelists—powerful type manipulation structures Patterns such as Visitor, Singleton, Command, and Factories Multi-method engines For each generic component, the ...

    C++ template 中文版

    当标准模板无法满足特定类型的需求时,可以通过特化(specialization)或偏特化(partial specialization)来进行定制。特化是为特定类型创建一个新的模板实现,而偏特化是为一部分模板参数创建特化的版本。 5. **...

    C++ TEMPLATE

    5. **模板偏特化(Template Partial Specialization)**: 类模板可以进行偏特化,这意味着可以为模板的部分类型参数提供特化实现。这在处理模板模板参数时尤其有用,例如在设计泛型容器的容器时。 6. **模板元...

    Modern C++ Design Generic Programming and Design Patterns Applied .pdf

    - **部分模板特化** (Partial template specialization):这是一种强大的技术,可以通过不同的参数组合来特化模板的一部分。 - **类型列表** (Type lists):这是用于强大类型操作的数据结构,可以用来存储和操作类型...

    Exploring C++ 11

    Part 3: Generic Programming – Template Specialization Part 3: Generic Programming – Partial Specialization Part 3: Generic Programming – Names and Namespaces Part 3: Generic Programming – ...

    C++ Templates

    6. **模板的部分特化(Template Partial Specialization)** - 类模板的特性,允许为模板的部分参数提供特化。 - 例如,为只改变第一个类型参数的`MyClass, T2&gt;`提供特化版本。 7. **模板元编程(Template ...

    易学c++配套电子教案16-20章ppt格式

    模板的特化(template specialization)和偏特化(partial specialization)也是本章可能涉及的内容。 第20章:异常的处理 C++的异常处理机制为程序提供了错误处理的方法。本章可能会讲解try、catch和throw关键字的...

    C++模板中文版及源代码

    - 偏特化(partial specialization)仅对模板的部分参数进行特化。 4. **模板元编程**: - C++模板元编程是一种在编译时执行计算的技术,利用模板的性质来生成代码。 - Boost库中的Type Traits和 MPL(Meta ...

    C++Templates_c++templates_C++Templates全览_healthbhr_源码.rar

    - **部分特化(Partial Specialization)**:针对模板的部分参数进行特化,仅适用于类模板。 4. **模板元编程(Metaprogramming)** - **编译时计算(Compile-Time Computation)**:利用模板在编译阶段进行计算...

    C++之Modern C++ Design.pdf

    2. **部分模板特化**(Partial Template Specialization):允许程序员为模板的部分参数提供特定的实现,从而可以根据某些类型的特性提供定制化的版本。 - **通用实例**:定义模板的基本行为。 - **特化实例**:...

    C++ Templates 源码 (官方源码离线完整版)

    - **部分特化(Partial Specialization)**:针对模板的一部分进行特化,仅适用于类模板。 5. **模板元编程(Template Metaprogramming)**: - 使用模板作为编程工具,允许在编译时进行计算,例如,`std::enable...

    Effective C++ More effective C++ 中文版 .chm .rar

    6. 掌握C++中的模板偏特化(Partial Specialization)和全特化(Full Specialization),以增强泛型编程的能力。 7. 使用引用绑定非NULL指针,以确保对象总是有效。 8. 避免在析构函数中使用成员函数,因为此时对象...

    c++函数库查询辞典

    4. C++99标准:C++99是C++的一个重要版本,引入了若干新特性,如命名空间(namespace)、内联变量(inline variables)、局部类(local classes)、模板的部分特化(partial template specialization)、迭代器分类...

    Modern C++ Design英文版.pdf

    3. Partial Template Specialization:本书介绍了部分模板特化的技术,用于实现复杂的模板metaprogramming。 4. Typelists:本书介绍了typelists的概念,即一种强大的类型操作结构,用于实现复杂的类型操作。 5. ...

    C&C++面经.zip

    - 模板特化(partial specialization) - 模板元编程(template metaprogramming) 13. **并发与多线程** - 线程(pthread库,C++11的std::thread) - 同步机制(mutex, semaphore, condition_variable) - ...

    计算机等级考试二级C++复习资料.pdf

    6. 模板的特化和偏特化(Template Specialization and Partial Specialization): 在Vector类模板的实现中,出现了模板特化的情况,如设置模板参数N可以定义一个具有特定大小的向量。这表明了如何在模板编程中对...

    模板类(template实现)殷人昆

    6. **模板偏特化(Partial Template Specialization)** 对于部分模板参数,可以创建偏特化版本。这在处理模板模板参数或者当部分类型参数需要特殊处理时很有用。 7. **模板的继承与多态** 模板类也可以作为...

Global site tag (gtag.js) - Google Analytics