2013-06-25 103 views
-1

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

#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);

+0

请注意,您引用的代码没有意义,因为您正在为循环内的字符分配布尔值。你可能想用'toupper()'来代替。 –

+0

是的。在发布问题后几秒钟,我意识到。哈哈! – Slay

+5

你指的是* dereferencing *,而不是引用。 –

回答

9

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

例如,标准advance函数将迭代器作为其参数。因此,您通过迭代无解引用它,因为在

std::advance(it, n); 

但是,如果你有一个指向一个int迭代器并且要通过4来增加该整数,你需要

(*it) += 4; 

我建议你应该阅读a good book on C++

顺便说一句,你的整个循环可以通过一个单一的调用来替代改造

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

嘿,谢谢。我目前正在阅读C++ primer第5版。它会好起来的。有什么更好的,你可以推荐?我已经看过你发布的帖子,但是我没有足够的经验去挑选出好的帖子。 – Slay

+2

@Armen'toupper'是一个重载函数,你的'transform'例子不能保证工作。请参阅http://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.simple –

+0

@JonathanWakely我被告知,传递可能的负值到''是形式上未定义的行为,应该总是将参数转换为'unsigned char'。 – jrok

4

你必须能够在迭代器本身例如执行操作您的代码确实it != s.end()++it

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

必须有一些操作指示要参考的东西它指的不是迭代器本身,否则,如果你测试if (it == another_it)如何将编译器知道,如果你试图比较迭代器或他们指向的东西?这同样适用于++it操作,该操作要修改迭代器,而不是它指向的东西。

迭代器可以有一个get()成员返回他们指的是东西,所以你会做isupper(it.get())而是他们所支持的引用操作,这是打字少,与指针相一致,并允许指针的任何代码中使用期望迭代器。

1

为了区分指针T上的操作和主体T上的操作,必须有一个解引用操作符。

例如:

int* x = ...; 

x++; 

你的意思是你想增加指针,以便它指向内存中的下诠释?还是你想增加x指向的int?

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

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

对比与参考:

int& x = ...; 

x++; 

引用具有替代性语义,并且不需要解引用。引用T的操作适用于主题T.缺点是不能修改引用本身。

相关问题