为什么我需要取消引用迭代器?例如,在以下程序中
#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。缺点是不能修改引用本身。