我只是尝试使用 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
验证)又是 iterator
到 char
(适用于std::string::erase
)?为什么它不等同于最后一个循环中的 iterator
?在我看来,它们的功能应该完全相同。
最佳答案
在基于范围的 for
循环中 i
的类型是 char
,因为字符串的元素是字符(更正式地说, std::string::value_type
是 char
的别名)。
当您将它传递给 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/