如何在迭代时从地图中删除?喜欢:
std::map<K, V> map;
for(auto i : map)
if(needs_removing(i))
// remove it from the map
Run Code Online (Sandbox Code Playgroud)
如果我使用map.erase它将使迭代器无效
class Help
{
public:
Help();
~Help();
typedef std::set<string> Terms;
typedef std::map<string, std::pair<int,Terms> > TermMap;
typedef std::multimap<int, string, greater<int> > TermsMap;
private:
TermMap terms;
TermsMap termsMap;
};
Run Code Online (Sandbox Code Playgroud)
我们怎样才能找到所使用的内存(以字节为单位)的对象term和termsMap.我们有图书馆吗?
我有一个向量。我需要删除其中的最后 3 个元素。描述了这个逻辑。程序崩溃。可能是什么错误?
vector<float>::iterator d = X.end();
for (size_t i = 1; i < 3; i++) {
if (i == 1) X.erase(d);
else X.erase(d - i);
}
Run Code Online (Sandbox Code Playgroud) 使用XCode 4.6在Mac OS X上测试.
此示例代码显示std::list正如我所期望的那样删除工作的最后一个元素:迭代器引用list::end()仍然是"1结束"并且仍然有效,即使删除了最后一个元素.
但第二个例子反驳了我的直觉.删除列表的第一个元素会发生变化list::rend(),我认为这是"从头开始".
我的期望是错的吗?为什么这是错的?为什么通过删除最后一个元素引用"1结束"仍然有效(如果不是?),但.rend()删除前元素后对"1(在开头()前面"的引用变为无效?
void printList( list<int>& os )
{
for( int& i : os )
printf( "%d ", i ) ;
puts("");
}
void testList()
{
list< int > os ;
os.push_back( 1 ) ;
os.push_back( 2 ) ;
os.push_back( 3 ) ;
os.push_back( 4 ) ;
os.push_back( 5 ) ;
// Forward iterators: reference to .end() not invalidated when remove last elt. …Run Code Online (Sandbox Code Playgroud) 我最近了解了在C++中使用反向迭代器的正确方法(特别是当你需要擦除它时).(见这个问题,并且这一个.)
这就是你应该这样做的方式:
typedef std::vector<int> IV;
for (IV::reverse_iterator rit = iv.rbegin(), rend = iv.rend();
rit != rend; ++rit)
{
// Use 'rit' if a reverse_iterator is good enough, e.g.,
*rit += 10;
// Use (rit + 1).base() if you need a regular iterator e.g.,
iv.erase((rit + 1).base());
}
Run Code Online (Sandbox Code Playgroud)
但我认为这样做要好得多(不要这样做,不符合标准,正如MooingDuck指出的那样):
for (IV::iterator it = iv.end(), begin = iv.begin();
it-- != begin; )
{
// Use 'it' for anything you want
*it += 10;
iv.erase(it); …Run Code Online (Sandbox Code Playgroud) 我刚写了下面的代码,并且很惊讶它不编译:
std::deque<int> container;
// filling the container...
for (auto it = container.rbegin(); it != container.rend(); ++it)
if (*it == 5)
{
container.erase(it);
break;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我想删除符合特定条件的最后一个元素(如果有).
错误是
调用std :: deque :: erase没有匹配函数(std :: reverse_iterator ...
起初我不相信它是由反向迭代器引起的,但事实确实如此,因为替换rbegin/ rend使用begin/ end解决它.
那么,2个问题:
我正在尝试解决 C++ 中的一个问题,其中一部分要求我使用rbegin()成员函数从向量中删除元素。但是,每次我编写下面提到的代码时,编译器都会抛出错误。这里有什么问题?
int main() {
int a = 1, b = 2;
vector<int> V = {a, b};
auto it = V.rbegin();
V.erase(it);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用begin()成员函数访问相同的元素,它编译得很好。下面的代码工作正常。
int main() {
int a = 1, b = 2;
vector<int> V = {a, b};
auto it = V.begin()+1;
V.erase(it);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我查看了一些C++容器(vector,deque,list,map,set),发现它们都没有实现
erase(reverse_iterator position)
Run Code Online (Sandbox Code Playgroud)
有一种方法可以从reverse_iterator获取迭代器,如本答案中所述.
但是为什么上面的容器没有用reverse_iterator参数实现擦除成员函数?
迭代器和reverse_iterator之间是否有任何显着差异,这使得这样的实现很难或者由于其他原因而没有实现?
关于这里提供的答案:如何使用反向迭代器调用erase
++it当使用-std = c ++ 11在g ++ 4.8.4中编译时,以下结果导致分段错误(on ).我误解了答案吗?
std::map<int,int> testmap;
testmap[0] = 1;
for(auto it=testmap.rbegin(); it!=testmap.rend(); ++it) {
testmap.erase( std::next(it).base() );
}
Run Code Online (Sandbox Code Playgroud)