IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++模板编程之类型萃取 惊鸿一瞥 -> 正文阅读

[C++知识库]C++模板编程之类型萃取 惊鸿一瞥

@著作权归作者所有:来自CSDN博客作者大胡子的艾娃的原创作品,如需转载,请注明出处https://blog.csdn.net/qq_43148810,否则将追究法律责任。
如有错误的地方欢迎指正,谢谢!

一、从模板函数std::distance(计算迭代器的距离)开始

#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <stack>
#include <set>
#include <map>

int main(int argc, char*argv[])
{
	std::vector<int> vec;
	for (int i = 0; i < 10; ++i)
	{
		vec.push_back(i);
	}
	///stack、queue、priority_queue无迭代器
	///vector、deque有operator-的实现,而list、set、map没有
	auto d = vec.end() - vec.begin();
	///distance函数对各类型迭代器都支持,计算迭代器之间的距离
	auto itrDis = std::distance(vec.begin(), vec.end());
	return 0;
}

大胡子的艾娃
1、stack、queue、priority_queue容器无迭代器,即不能使用此函数。
2、vector、deque容器重载了operator-,实现了计算std::distance功能。内存连续型(迭代器可跳跃)容器,距离为迭代器直接相减。

_NODISCARD difference_type operator-(const _Mybase& _Right) const
	{	// return difference of iterators
	return (*(_Mybase *)this - _Right);
	}

3、list、set、map容器没有实现operator-,内存不连续型(迭代器不可跳跃)容器。

二、distance模板函数实现剖析

//_Distance1的两个重载版本begin
template<class _InIt>
	_CONSTEXPR17 _Iter_diff_t<_InIt> _Distance1(_InIt _First, _InIt _Last, input_iterator_tag)
	{	// return distance between iterators; input
	_Iter_diff_t<_InIt> _Off = 0;
	for (; _First != _Last; ++_First)
		{
		++_Off;
		}

	return (_Off);
	}

template<class _RanIt>
	_CONSTEXPR17 _Iter_diff_t<_RanIt> _Distance1(_RanIt _First, _RanIt _Last, random_access_iterator_tag)
	{	// return distance between iterators; random-access
	return (_Last - _First);
	}
//_Distance1的两个重载版本end

//迭代器的类型萃取begin	
template<class _Iter>
	using _Iter_cat_t = typename iterator_traits<_Iter>::iterator_category;
//迭代器的类型萃取end

//distance函数begin	
template<class _InIt>
	_NODISCARD _CONSTEXPR17 _Iter_diff_t<_InIt> distance(_InIt _First, _InIt _Last)
	{	// return distance between iterators
	return (_Distance1(_First, _Last, _Iter_cat_t<_InIt>()));
	}
//distance函数end

1、由_Distance1函数实现,并且_Distance1有两个重载版本(VS2017),其他编译器可能有多个,但并无分别。
2、由第三参数类型input_iterator_tag和random_access_iterator_tag用来重载,也仅仅是用来重载,并未使用类型对象。
3、_Iter_cat_t<_InIt>()则用来萃取(向迭代器提问)其类型,而iterator_category即是答案。

typename T::iterator_category cagy2;		//等同于迭代器的类型萃取

4、迭代器除了可以回答与之容器对应的迭代器类型,还可以回答一下类型。

typedef bidirectional_iterator_tag iterator_category	//迭代器的分类
typedef ptrdiff_t difference_type						//iterator之间的距离
typedef size_t	size_type								//分配内存大小
typedef T value_type
typedef T* pointer
typedef &T reference

例如:

typename std::iterator_traits<T>::difference_type diff_type;

5、迭代器的五种类型,按移动性质分类,不是枚举、常量宏等类型,为struct,属性在此等同class,并且有继承关系。

struct input_iterator_tag
	{	// identifying tag for input iterators
	};

struct output_iterator_tag
	{	// identifying tag for output iterators
	};

struct forward_iterator_tag
	: input_iterator_tag
	{	// identifying tag for forward iterators
	};

struct bidirectional_iterator_tag
	: forward_iterator_tag
	{	// identifying tag for bidirectional iterators
	};

struct random_access_iterator_tag
	: bidirectional_iterator_tag
	{	// identifying tag for random-access iterators
	};

6、_Distance1模板函数只实现的两个重载版本(内存是否连续型或者说迭代器是否可跳跃),因为继承关系其他类型向上兼容。VS2017只有该两个版本,其他版本编译器可能有多个版本。

到此完完全全讲清楚了模板函数std::distance怎么实现计算迭代器之间的距离。
如对容器的数据结构,底层实现不清楚的可参考:
C++STL容器总结:https://blog.csdn.net/qq_43148810/article/details/118229552

三、类型萃取,惊鸿一瞥 ,STL六大组件关系

大胡子的艾娃
总结:Container通过Allocator取得数据的储存空间,Algorithm通过Iterator存取Container内容,Functor可以协助Algorithm完全不同的策略变化,Adapter可以修饰或者套接Functor。

1、std::distance(计算迭代器的距离)算法很好的解释了以上“总结”斜线部分。
2、STL称之为标准模板库,C++面对对对象语言,标准库多为模板编程、元编程的手法,而非面对对象的手法。换而言之多为静态多态性,而非虚函数代表的动态多态性。
3、traits(萃取机)并非六大组件,但是在STL中起到至关重要的作用。
4、由此打开元编程(对类型操作,而非对象)的大门

更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-18 12:31:35  更:2021-08-18 12:32:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 6:06:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计