为什么我需要取消引用迭代器



为什么我需要取消引用迭代器?例如,在以下程序中

#include <iostream>
#include <string>
#include <vector>
int main()
{
    using namespace std;
    string s("some string");
    for(auto it = s.begin(); it != s.end(); && !isspace(*it); ++it)
        *it = isupper(*it);
    cout<<s;
}

为什么需要使用isupper(*it);而不仅仅是isupper(it);

Iterator是一个通用指针。它指向某个东西。如果你有一个函数需要这个东西(在这种情况下是char或int),而不是"指针"本身,你需要取消引用迭代器。

例如,标准的advance函数将迭代器作为其参数。因此,您传递迭代器而不取消对它的引用,如中所示

std::advance(it, n);

但是,如果您有一个指向int的迭代器,并且您想将该整数递增4,则需要

(*it) += 4;

我建议你读一本关于C++的好书。

顺便说一句,你的整个循环可以被一个转换的调用所取代

 std::transform(s.begin(), s.end(), s.begin(), toupper);

您需要能够对迭代器本身执行操作,例如您的代码执行it != s.end()++it

有时,您需要能够对迭代器指向的对象执行操作,例如isupper(*it)

必须有一些操作来指示您想要引用它所指的东西,而不是迭代器本身,否则,如果您测试if (it == another_it),编译器如何知道您是在尝试比较迭代器还是它们所指的事情?这同样适用于++it操作,它想要修改迭代器,而不是它所指向的东西

迭代器可以有一个get()成员来返回它们引用的东西,所以你可以使用isupper(it.get()),但它们支持去引用运算符,该运算符类型较少,与指针一致,并允许在任何需要迭代器的代码中使用指针。

为了区分对pointer-to-T的操作和对主题T的操作,有必要使用一个解引用运算符。

例如:

int* x = ...;
x++;

你的意思是你想增加指针,使它指向内存中的下一个int吗?还是要将指向的int增加x?

如果没有延迟运算符,这将是不明确的。

迭代器只是指针接口的一个泛化。

与参考文献对比:

int& x = ...;
x++;

引用具有替代语义,不需要取消引用。对T引用的操作适用于主题T。缺点是不能修改引用本身。

最新更新