【问题标题】:Dereferencing Iterator解引用迭代器
【发布时间】:2022-10-20 01:19:49
【问题描述】:
#include <iostream>
#include<string>
using std::string;
using namespace std;


int main()
{
    string s("some string");
    
    
      *s.begin() = toupper(*s.begin());
      
   
      std::cout << s << std::endl;
      
}

结果是:

一些字符串

为什么必须使用 *s.begin() ? 为什么我不能只使用 s.begin() ?喜欢:

s.begin() = toupper(s.begin());

为什么必须在迭代器前面使用解引用运算符 * ?

在 C++ prime FIFTH EDITION P.107 一书中,它说我们取消引用该迭代器以将该字符传递给 toupper 并将大写字母 S 返回到原始字符串。

但我还是不明白,为什么我们不能直接使用 s.begin() 。 指针不只是为了节省内存吗?

【问题讨论】:

  • 迭代器与指针非常相似,但如果s.begin() 是一个指针,那么你也不能给它分配一个字符,你也必须取消引用它。
  • “指针不就是为了节省内存吗?”不。一点也不。令人惊讶的是,为什么这种误解如此持久。
  • 迭代器不能是字符或对它的引用,因为然后递增它会给出例如'B' 而不是 'A',而不是字符串中的下一个字符。当然,可以用户定义分配并转换为char,但这可能会产生意想不到的副作用,并可能引入歧义(您想要增加什么?)。相反,引入了operator*(),它实现起来很简单,提供了一个清晰、明确的API,解决了所有用户需求,并且在用户端只涉及最少的额外(并且非常直观)的冗长。
  • 你可以实现一个迭代器,然后一切都会清楚。如果我没记错的话,它已经在书中实现了。
  • 对于第一个字符,您可以使用 s.front() 而不是 *s.begin()

标签: c++


【解决方案1】:

假设您将使用指针:

 string s("some string");
 auto ptr = s.data();     // pointer to first character

然后你仍然需要取消引用它才能分配一个字符:

 *ptr = 'X';

指针增加了一层间接性。指针不是它指向的东西。您必须取消引用指针才能访问指针对象。关于迭代器是相同的。字符串的迭代器不是字符,尽管您可以通过迭代器访问字符。

【讨论】:

    【解决方案2】:

    如果您阅读有关std::string 的文档,您可以看到begin() 的原型是iterator begin(),它返回一个iterator

    toupper()的原型是 int toupper ( int c );。它返回 int 并接受 int

    在这里,您很想将一个 int(从 toupper() 返回)分配给一个迭代器(从 s.begin() 返回)。你将一个迭代器传递给toupper(),它接受int

    s.begin() = toupper(s.begin()); // iterator = int(iterator)
    

    如果您取消引用迭代器,它将返回它指向的值的引用。 (char&amp;)

    *s.begin() = toupper(*s.begin()); // int = int(char)
    

    请记住,您使用的是带有迭代器的引用,而不是直接使用指针。

    【讨论】:

    • 最后的评论应该真的像char = int(char)
    【解决方案3】:

    迭代器是帮助循环遍历对象的指针。在这种情况下 s.begin() 是一个指针,因此为了访问它的值,您必须使用“*”取消对它的引用。

    【讨论】:

    • “迭代器是指针”可能是,通常不是
    【解决方案4】:

    s.begin() 返回一个迭代器(类似对象的指针),指向字符串中的第一个字符。如果要为迭代器指向的内存分配一个值,则需要取消引用 (*) 它(就像使用指针一样)。

    【讨论】:

    • “返回一个指针” .... 不。
    猜你喜欢
    • 2013-08-12
    • 2016-01-25
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    相关资源
    最近更新 更多