*在C++中的目的是什么?

-11 c++ iterator dereference

int main()
{
    string s("some string");
    if (s.begin() != s.end())
        auto it = s.begin();
    *it = toupper (*it) ; // Error ; the identifier "it" is undefined 
}
Run Code Online (Sandbox Code Playgroud)

为什么*它未定义?为什么我们需要在迭代器维度中使用dereference?

Pix*_*ist 10

  1. 代码不起作用,因为itif分支的范围内定义.
  2. 需要解除引用才能访问迭代器引用的实际"内容".

说明

1.为什么it选择语句后未定义?

该标准在第6.4/1节中说明(强调我的):

selection-statement中的子语句(每个子语句,if语句的else形式)隐式定义块作用域(3.3).如果selection-statement中的子语句是单个语句而不是复合语句,则就好像它被重写为包含原始子语句的复合语句一样.

标准中给出的示例与手头的情况相符.

例:

if (x) int i;

可以等同地重写为

if (x) { int i; }

现在我们需要通过查看引用的§3.3(再次强调我的)来了解(隐式)块范围如何影响变量的"可见性" :

块(6.3)中声明的名称是该块的本地名称; 它有块范围.潜在范围从其声明点(3.3.2)开始,到其块结束时结束.在块作用域中声明的变量是局部变量.

=>你去了:你的变量it在一个块中,it结束的范围在块的末尾.因此在该块之后未定义.

2.为什么要取消引用迭代器来访问内容?

迭代器的conecept构建为抽象指针,如第24章中标准中的Iterator库所述.因此,迭代器引用类似指针的引用也引用了一个值.解除引用是访问实际引用值的C++方法.

取消引用指针意味着"给我存储在指针的内存地址的值",而取消引用迭代器意味着"给我存储在该点的值,迭代器逻辑引用".

(注意:指针只是一种特殊的迭代器.)

该标准要求每个迭代器类型定义解除引用操作.

§24.2.1/ 1

所有输入迭代器都支持表达式*i,从而产生一些对象类型T,称为迭代器的值类型.所有输出迭代器都支持表达式*i = o,其中o是某些类型的值,该类型位于可写入特定迭代器类型的类型集中i.

每个迭代器类型都是输入或输出.

§24.2.1/ 2:迭代器的类型

本国际标准根据它们定义的操作定义了五类迭代器:输入迭代器,输出迭代器,前向迭代器,双向迭代器和随机访问迭代器[.]

§24.2.1/ 3:迭代器类型的相关性

前向迭代器满足输入迭代器的所有要求,并且可以在指定输入迭代器时使用; 双向迭代器也满足前向迭代器的所有要求,并且可以在指定前向迭代器时使用; 随机访问迭代器也满足双向迭代器的所有要求,并且可以在指定双向迭代器时使用.

=>迭代器提供间接(以比指针更通用的方式)并且需要被解引用以跟随间接,访问它们的值.

3.工作实例

#include <string>
#include <cctype>
int main()
{
  std::string s("some string");
  if (s.begin() != s.end())
  {
    auto it = s.begin();
    *it = std::toupper(*it); 
  }
  // it not defined here
  return 0; 
}
Run Code Online (Sandbox Code Playgroud)

  • 至少有机会获得"逆转"徽章;) (2认同)