模版大致分为三种版本:普通版本、部分特化版本、全部特化版本。
普通版本:
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;
}
结果如下:
这样,在编译时就能确定调用哪种版本的函数,比在运行时判断,效率提高了。