模版特化和作为萃取器的应用

模版大致分为三种版本:普通版本、部分特化版本、全部特化版本。
普通版本:

template <class type>
void function(type t){}

部分特化版本:

template <class type>
void function(type *t){}

全部特化版本:

template <>
void function<int>(int t){}

其中,全部特化版本只能接受一种参数,范围最小;部分特化版本可以接受一类特定的参数,范围较大;普通版本可以接受任何参数,范围最大。

模版的匹配规则如下:
全部特化版本 ----> 部分特化版本 ----> 普通版本
(高优先级)----------------------------->(低优先级)

如何做到原生指针和迭代器有相同的功能呢?

1.制作类模版萃取器。

//iterator_trait是模版类,由三个版本组成:一个普通版本,两个部分特化版本(用来萃取原生指针)
//作用是萃取器,放进去任意类型,萃取出相应的5个类型
template <class it>
class iterator_trait
{
public:
	typedef typename it::iterator_category		iterator_category;
	typedef typename it::value_type				value_type;
	typedef typename it::difference_type		difference_type;
	typedef typename it::pointer				pointer;
	typedef typename it::reference				reference;
};
template <class it>
class iterator_trait<it *>
{
public:
	typedef random_iterator_flag		iterator_category;
	typedef it							value_type;
	typedef distance_t					difference_type;
	typedef it *						pointer;
	typedef it &						reference;
};
template <class it>
class iterator_trait<const it *>
{
public:
	typedef random_iterator_flag		iterator_category;
	typedef it							value_type;
	typedef distance_t					difference_type;
	typedef const it *					pointer;
	typedef const it &					reference;
};

2.制作函数模版萃取器。

//用函数模版当萃取器,只萃取迭代器类型
template <class it>
typename it::iterator_category iterator_trait(const it &)
{
	typedef typename it::iterator_category iterator_category;
	return iterator_category();
}
template <class it>
random_iterator_flag iterator_trait(it *)
{
	return random_iterator_flag();
}
template <class it>
random_iterator_flag iterator_trait(const it *)
{
	return random_iterator_flag();
}
//利用萃取器,打印迭代器自身类型
template <class it>
void print_iterator_type(it _it)
{
	//typedef typename iterator_trait<it>::iterator_category type;
	my_print_type(iterator_trait(_it));
}

用萃取器的一个例子(类模版):

typedef int distance_t;

//下面5个是五种迭代器类型的标志,用来区分迭代器类型
class input_iterator_flag{};
class output_iterator_flag{};
class forward_iterator_flag : public input_iterator_flag{};
class bidirectional_iterator_flag : public forward_iterator_flag{};
class random_iterator_flag : public bidirectional_iterator_flag{};


//迭代器类的基类
template <class category, class type, class diff = distance_t,
class ptr = type *, class refer = type &>
class iterator
{
public:
	typedef category		iterator_category;
	typedef type			value_type;
	typedef diff			difference_type;
	typedef ptr				pointer;
	typedef refer			reference;
};


//五种迭代器,由基类派生,标签不同,用来区分迭代器自身类型
template <class type, class distance>
class input_iterator : public iterator<input_iterator_flag, type, distance>{};
template <class type, class distance>
class output_iterator : public iterator<output_iterator_flag, type, distance>{};
template <class type, class distance>
class forward_iterator : public iterator<forward_iterator_flag, type, distance>{};
template <class type, class distance>
class bidirectional_iterator : public iterator<bidirectional_iterator_flag, type, distance>{};
template <class type, class distance>
class random_iterator : public iterator<random_iterator_flag, type, distance>{};


template <class type>
class my_vector
{
public:
	class const_iterator : public random_iterator<type, int>{};
	class iterator : public const_iterator{};
};
template <class type>
class my_list
{
public:
	class const_iterator : public bidirectional_iterator<type, int>{};
	class iterator : public const_iterator{};
};

//iterator_trait是模版类,由三个版本组成:一个普通版本,两个部分特化版本(用来萃取原生指针)
//作用是萃取器,放进去任意类型,萃取出相应的5个类型
template <class it>
class iterator_trait
{
public:
	typedef typename it::iterator_category		iterator_category;
	typedef typename it::value_type				value_type;
	typedef typename it::difference_type		difference_type;
	typedef typename it::pointer				pointer;
	typedef typename it::reference				reference;
};
template <class it>
class iterator_trait<it *>
{
public:
	typedef random_iterator_flag		iterator_category;
	typedef it							value_type;
	typedef distance_t					difference_type;
	typedef it *						pointer;
	typedef it &						reference;
};
template <class it>
class iterator_trait<const it *>
{
public:
	typedef random_iterator_flag		iterator_category;
	typedef it							value_type;
	typedef distance_t					difference_type;
	typedef const it *					pointer;
	typedef const it &					reference;
};


void my_print_type(input_iterator_flag)
{
	std::cout << "i'm a input_iterator" << std::endl;
}
void my_print_type(output_iterator_flag)
{
	std::cout << "i'm a output_iterator" << std::endl;
}
void my_print_type(forward_iterator_flag)
{
	std::cout << "i'm a forward_iterator" << std::endl;
}
void my_print_type(bidirectional_iterator_flag)
{
	std::cout << "i'm a bidirectional_iterator" << std::endl;
}
void my_print_type(random_iterator_flag)
{
	std::cout << "i'm a random_iterator" << std::endl;
}


//利用萃取器,打印迭代器自身类型
template <class it>
void print_iterator_type(it _it)
{
	typedef typename iterator_trait<it>::iterator_category type;
	my_print_type(type());
}

int main()
{
	my_vector<int>::iterator vector_it;
	my_list<char>::iterator list_it;
	double ary[10] = {0};
	print_iterator_type(vector_it);
	print_iterator_type(list_it);
	print_iterator_type(ary);
	return 0;
}

结果如下:
在这里插入图片描述

这样,在编译时就能确定调用哪种版本的函数,比在运行时判断,效率提高了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值