简体   繁体   English

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

[英]Deleting whitespace from a string via an iterator to the string in a C++11 range-based for loop

I'm simply trying to delete all the whitespace from a string using C++11's range-based for loop; 我只是尝试使用C ++ 11的基于范围的for循环从字符串中删除所有空格; however, I keep getting std::out_of_range on basic_string::erase . 但是,我一直在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;

}

So I'm wondering: what exactly is i in the first two loops? 所以我想知道:究竟什么是i的第一个两个环? Why is it seemingly both a char (as verified by typeid ) and an iterator to a char (works with std::string::erase )? 为什么它看起来既是char (由typeid验证)又是chariterator (与std::string::erase )? Why isn't it equivalent to the iterator in the last loop? 为什么它不等同于最后一个循环中的iterator It seems to me that they should function exactly the same. 在我看来,它们应该完全相同。

The type of i in the range-based for loop is char , since the elements of a string are characters (more formally, std::string::value_type is an alias for char ). 基于范围的for循环中的i类型是char ,因为字符串的元素是字符(更正式地说, std::string::value_typechar的别名)。

The reason why it seems to work as an iterator when you pass it to erase() is that an overload of erase() exists that accepts an index and a count, but the latter has a default argument: 为什么它似乎迭代器当你通过它来工作的原因erase()是一个过载erase()存在接受索引和计数,但后者有一个默认的说法:

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

And on your implementation char happens to be implicitly convertible to std::string::size_type . 在您的实现上, char恰好可以隐式转换为std::string::size_type However, this is likely not doing what you expect. 但是,这可能没有达到预期效果。

To verify that i is not indeed an iterator, try dereferencing it and you will see the compiler screaming: 要验证i确实不是迭代器,请尝试解除引用它,您将看到编译器尖叫:

*i; // This will cause an error

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM