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

时间:2015-02-02 22:36:17

标签: 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 
}

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

1 个答案:

答案 0 :(得分:10)

  1. 代码不起作用,因为在it分支的范围内定义了if
  2. 需要取消引用才能访问实际的“内容”,迭代器正在引用。
  3. 说明

    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:迭代器类型的相关性

      

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

    <强> =&GT;迭代器提供间接(以比指针更通用的方式)并且需要取消引用以跟随间接,访问值。

    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; 
    }