c++ - 通过迭代器从字符串中删除空格到基于 C++11 范围的 for 循环中的字符串

标签 c++ string c++11 iterator auto

我只是尝试使用 C++11 的基于范围的 for 循环从字符串中删除所有空格;但是,我一直在 basic_string::erase 上收到 std::out_of_range

#include <iostream>
#include <string>
#include <typeinfo>

int main(){

  std::string str{"hello my name is sam"};

  //compiles, but throws an out_of_range exception
  for(auto i : str){
    std::cout << typeid(i).name();  //gcc outputs 'c' for 'char'
    if(isspace(i)){
      str.erase(i);
    }
  }
  std::cout << std::endl;

  //does not compile - "invalid type argument of unary '*' (have 'char')"
  for(auto i : str){
    if(isspace(*i)){
      str.erase(i);
    }
  }

  //works exactly as expected
  for(std::string::iterator i = begin(str); i != end(str); ++i){
    std::cout << typeid(*i).name();  //gcc outputs 'c' for 'char'
    if(isspace(*i)){
      str.erase(i);
    }
  }
  std::cout << std::endl;

}

所以我想知道:前两个循环中的 i 到底是什么?为什么它看起来既是 char(由 typeid 验证)又是 iteratorchar(适用于std::string::erase)?为什么它不等同于最后一个循环中的 iterator?在我看来,它们的功能应该完全相同。

最佳答案

在基于范围的 for 循环中 i 的类型是 char,因为字符串的元素是字符(更正式地说, std::string::value_typechar 的别名)。

当您将它传递给 erase() 时,它似乎 用作迭代器的原因是 overload of erase() exists 接受一个索引和一个计数,但后者有一个默认参数:

basic_string& erase( size_type index = 0, size_type count = npos );

并且在您的实现中 char 恰好可以隐式转换为 std::string::size_type。但是,这很可能不符合您的预期。

要验证 i 确实不是迭代器,请尝试取消引用它,您会看到编译器尖叫:

*i; // This will cause an error

关于c++ - 通过迭代器从字符串中删除空格到基于 C++11 范围的 for 循环中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17021513/

相关文章:

c++ - 三角形 - 二维正方形相交测试

c++ - 如何使用控制台窗口中的输入顶点在 glut 中绘制多边形?

c++ - STL 扩展/修改最佳实践

c - 解析文件中的字符串并创建二叉树的程序中出现段错误

java - 如何查找字符串中第n次出现的字符?

c++ - 替换 std::binary_function

c++ - C++中的十六进制到十六进制

java - 如何从文本文件中读取输入并将这些输入放入 Java 中的 ArrayList 中?

c++ - c++ 11中的 future vector

c++ - 在 C++11 中,您能否将引用的基类传递给线程的构造函数并获得多态行为?