在c++ 11基于范围的for循环中,通过迭代器删除字符串中的空白
Deleting whitespace from a string via an iterator to the string in a C++11 range-based for loop
我只是想用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()
时,看起来像是作为迭代器工作的原因是存在erase()
的重载,它接受索引和计数,但后者有一个默认参数:
basic_string& erase( size_type index = 0, size_type count = npos );
在您的实现中,char
恰好可以隐式转换为std::string::size_type
。然而,这很可能是不是做您所期望的。
要验证i
确实不是一个迭代器,试着解引用它,你会看到编译器尖叫:
*i; // This will cause an error
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 不明白迭代器,引用和指针失效,一个例子
- 我可以使用反向迭代器作为ForwardIt吗
- ESP8266单片机矢量迭代器的C++问题
- 如何在C++中将迭代器作为函数参数传递
- 是否应避免从非常量迭代器转换为常量迭代器?
- 如何在 c++ 中将字符串迭代器变量传递给函数?
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?