C++ 通过迭代器将空白从字符串中删除到C++;11基于范围的for循环
我只是尝试使用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
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:说得好。我的回答主要集中在最后一段的第一个问题上,我没有深入分析:)谢谢你的指点