Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过迭代器将空白从字符串中删除到C++;11基于范围的for循环_C++_String_C++11_Iterator_Auto - Fatal编程技术网

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

C++ 通过迭代器将空白从字符串中删除到C++;11基于范围的for循环,c++,string,c++11,iterator,auto,C++,String,C++11,Iterator,Auto,我只是尝试使用C++11的基于范围的for循环删除字符串中的所有空格;但是,在basic\u string::erase上,我不断得到std::out\u of\u range #include <iostream> #include <string> #include <typeinfo> int main(){ std::string str{"hello my name is sam"}; //compiles, but throws an

我只是尝试使用C++11的基于范围的for循环删除字符串中的所有空格;但是,在
basic\u string::erase
上,我不断得到
std::out\u of\u 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;

}
#包括
#包括
#包括
int main(){
string str{“你好,我的名字是山姆”};
//编译,但抛出范围外异常
用于(自动i:str){

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

当您将其传递到
erase()
时,它似乎起到迭代器的作用,原因是存在一个接受索引和计数的函数,但后者有一个默认参数:

basic_string& erase( size_type index = 0, size_type count = npos );
在您的实现中,
char
恰好可以隐式转换为
std::string::size\u type

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

*i; // This will cause an error

我认为值得注意的是,结尾给出的for循环可能无法正常工作,因为
erase
可能会使循环迭代器无效。要解决此问题,可以使用
erase
返回的迭代器,尽管如果简单地使用,可能会导致性能不佳(循环将是最坏情况下的二次循环,而不是线性时间,因为擦除本身是最坏情况下的线性)。为了提高效率,您应该使用
std::remove
std::remove\u if
,或类似的实现,如@syam的回答中所建议的(编辑:已删除)@JohnBartholomew:说得好。我的回答主要集中在最后一段的第一个问题上,我没有深入分析:)谢谢你的指点