my_swap() 模板实例的具体情况。假设一个程序包含下面的代码:


以一
以一 2023-12-31 03:33:50 51559 赞同 0 反对 0
分类: 资源
std::vector words {"one", "two", "three"}; my_swap(std::begin(words), std::begin(words)+1); //Swap first two elements 当编译器遇到 my_swap() 调用时,它会生成一个基于调用参数的函数模板实例。模板类型的迭代器是 iterator。在 my_swap() 模板的主体中,编译器不得不处理 tmp 的定义,编译器知道模板的类型参数是 iterator,因此在向模板添加了这个类型后,tmp 的定义变为:

my_swap() 模板实例的具体情况。假设一个程序包含下面的代码:

  1. std::vector<std::string> words {"one", "two", "three"};
  2. my_swap(std::begin(words), std::begin(words)+1); //Swap first two elements

当编译器遇到 my_swap() 调用时,它会生成一个基于调用参数的函数模板实例。模板类型的迭代器是 iterator<std::string>。在 my_swap() 模板的主体中,编译器不得不处理 tmp 的定义,编译器知道模板的类型参数是 iterator<std::string>,因此在向模板添加了这个类型后,tmp 的定义变为:

  1. typename std::iterator_traits<iterator<std::string> >::value_type tmp = *a;

tmp 的类型现在是一个 iterator_traits 模板实例的成员变量。为了弄清楚这意味着什么,编译器需要使用 my_swap() 函数中用来指定 tmp 类型的类型参数来实例化 iterator_traits 模板。下面是一个编译器将会生成的 iterator_traits 模板实例:

  1. struct iterator—traits
  2. {
  3. typedef typename iterator<std::string>::difference_type difference_type;
  4. typedef typename iterator<std::string>::value_type value_type;
  5. typedef typename iterator<std::string>::pointer pointer;
  6. typedef typename iterator<std::string>::reference reference;
  7. typedef typename iterator<std:: string>:: iterator_category iterator_category;
  8. }

从这里编译器可以确定 tmp 的类型为 iterator_traits<iterator<std::string>>::value_type,然而它也是 iterator<std::string>::value_type 的别名。就像所有的 STL 迭代器类型,iterator<std::string> 类型的定义是从 iterator 模板中生成的,并且会包含 value_type 的定义, 看起来像下面这样:

  1. typedef std::string value_type;

现在编译器从 iterator_traits 实例中知道 itemtor_traits<itemtor<std::string>>::value_type 是 iterator<std::string>::value_type 的别名,并且从 itemtor<std::string> 类定义中知道 iterator<std::string>:: value_type 是 std::string 的别名。通过将别名转换为真实类型,编译器推断出 my_swap() 函数中 tmp 的定义是:

  1. std::string tmp = *a;

有必要提醒自己模板不是代码一它是编译器用来生成代码的配方。iterator_traits 模板只包含类型别名,因此不会产生可执行代码。编译器在生成 C++ 代码的过程中,会用到它。被编译的代码中将不会有 iterator_traits 模板的踪迹;它的唯一用武之地是在生成 C++ 代码的过程中。

这里仍然遗留了一些有关指针的问题。iterator_traits 如何让算法像接受迭代器一样接受指针。iterator_traits 模板特化了类型 T* 和 const T* 的定义。例如,当模板类型参数是指针类型 T* 时,特化被定义为:

  1. template<class T>
  2. struct iterator_traits<T*>
  3. {
  4. typedef ptrdiff_t difference_type;
  5. typedef T value_type;
  6. typedef T* pointer;
  7. typedef T& reference;
  8. typedef random_access_iterator_tag iterator_category;
  9. }

当模板类型参数是指针类型时,这定义了对应于别名的类型。T* 类型的指针 value_type 的别名总是为 T;如果将 Box* 类型的指针作为 my_swap() 的参数,那么 value_type 的别名是 Box,因此 tmp 也为这种类型。

随机访问迭代器类别所要求的全部操作都可以运用到指针上。因此对于指针,iterator_categor 的别名总是等同于 std::random_access_iterator_tag 类型。因而 iterators_traits 能否正常工作取决于模板类型参数是指针还是迭代器类类型。当模板类型参数是指针时,会选择使用 iterators_traits 针对指针的特例化模板;否则选择标准的模板定义。

如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
以一L0
粉丝 0 资源 1143 + 关注 私信
最近热门资源
银河麒麟桌面操作系统备份用户数据  121
统信桌面专业版【全盘安装UOS系统】介绍  114
银河麒麟桌面操作系统安装佳能打印机驱动方法  108
银河麒麟桌面操作系统 V10-SP1用户密码修改  100
最近下载排行榜
银河麒麟桌面操作系统备份用户数据 0
统信桌面专业版【全盘安装UOS系统】介绍 0
银河麒麟桌面操作系统安装佳能打印机驱动方法 0
银河麒麟桌面操作系统 V10-SP1用户密码修改 0
作者收入月榜
1

prtyaa 收益393.62元

2

zlj141319 收益217.55元

3

1843880570 收益214.2元

4

IT-feng 收益208.98元

5

风晓 收益208.24元

6

777 收益172.71元

7

Fhawking 收益106.6元

8

信创来了 收益105.84元

9

克里斯蒂亚诺诺 收益91.08元

10

技术-小陈 收益79.5元

请使用微信扫码

加入交流群

请使用微信扫一扫!