模板元编程之 std::iterator_traits<> 类型计算
我们来解析一段代码:
1 template<class..._Ty> 2 using void_t = void; 3 4 template <class, class = void> 5 struct _Iterator_traits_base {}; // empty for non-iterators 6 7 template <class _Iter> 8 struct _Iterator_traits_base<_Iter, 9 void_t<typename _Iter::iterator_category, typename _Iter::value_type, typename _Iter::difference_type, 10 typename _Iter::pointer, typename _Iter::reference>> { 11 // defined if _Iter::* types exist 12 using iterator_category = typename _Iter::iterator_category; 13 using value_type = typename _Iter::value_type; 14 using difference_type = typename _Iter::difference_type; 15 using pointer = typename _Iter::pointer; 16 using reference = typename _Iter::reference; 17 };
这段代码是我从C++标准库中截取到代码,首先看第一段,(1-2)定义了一个范围。
(4-5)定义了一个特化版本,用来停止迭代
(7-16)这是重点,首先声明了一个类型_Iter,然后下面紧跟的是算法实现部分,
方法名后面的是类型的声明,就是说,这个方法有,Iter,和类型集合类型。
然后再看,逻辑体,using 声明了传入类型的类型,这是什么意思呢,就是这个模板的成员属性,也是传入类型的属性,
比如传入一个容器的迭代器类型的时候访问的就是迭代器类型的类型:
1 std::iterator_traits<std::vector<int>::iterator>::value_type m = 100; 2 //m在这里就是一个int类型
有人就说了,我直接访问类型的迭代器类型不就行,为什么要多此一举呢?
我们可以使用这一个模板访问所有的此模板内的对象的属性类型,这就有效减少了代码的重复性
并且呢,此模板没有包含运行时的代码,所以呢,在编译期,代码就会被执行转换。这也是元编程的最重要的思想
上面写的std::iterator_traits 是继承自_Iterator_traits_base ,做了一个封装,

浙公网安备 33010602011771号