草庐IT

c++ - map , lambda ,remove_if

coder 2023-06-03 原文

所以,我对 std::map、lambda 和 STL 算法(remove_if)有疑问。实际上,与 std::list 或 std::vector 相同的代码效果很好。

我的测试示例:

#include <map>
#include <iostream>
#include <algorithm>

struct Foo
{
    Foo() : _id(0) {}
    Foo(int id) : _id(id)
    {

    }

    int _id;    
};
typedef std::map<int, Foo> FooMap;


int main()
{
    FooMap m;
    for (int i = 0; i < 10; ++i)
        m[i + 100] = Foo(i);

    int removeId = 6;
    // <<< Error here >>>
    std::remove_if(m.begin(), m.end(), [=](const FooMap::value_type & item) { return item.second._id == removeId ;} ); 

    for (auto & item : m )
        std::cout << item.first << " = " << item.second._id << "\n";    

    return 0;
}

错误信息:

In file included from /usr/include/c++/4.6/utility:71:0,
                 from /usr/include/c++/4.6/algorithm:61,
                 from main.cxx:1:
/usr/include/c++/4.6/bits/stl_pair.h: In member function ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::pair<_T1, _T2>&&) [with _T1 = const int, _T2 = Foo, std::pair<_T1, _T2> = std::pair<const int, Foo>]’:
/usr/include/c++/4.6/bits/stl_algo.h:1149:13:   instantiated from ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = std::_Rb_tree_iterator<std::pair<const int, Foo> >, _Predicate = main()::<lambda(const value_type&)>]’
main.cxx:33:114:   instantiated from here
/usr/include/c++/4.6/bits/stl_pair.h:156:2: error: assignment of read-only member ‘std::pair<const int, Foo>::first’

我不明白这里有什么问题。所以,我很高兴阅读一些关于它的建议/指导。我的目标 - 使用带有 std::map 和算法的新 lambda 样式,例如 remove_if。

g++ 4.6,-std=c++0x。

最佳答案

问题是std::map<K,V>::value_typestd::pair<const K, V> ,又名 .firstconst并且不可分配。 Lambda 与这里的问题无关。

std::remove_if 通过移动容器的元素来“删除”项目,以便所有不符合谓词的内容都在前面,在返回的迭代器之前。该迭代器之后的所有内容都未指定。它通过简单的分配来做到这一点,因为你不能分配给 const变量,你会得到那个错误。

姓名remove可能有点误导,在这种情况下,你真的想要 erase_if ,但是很可惜,那不存在。您将不得不遍历所有项目并使用 map.erase(iterator) 手动删除它们。 :

for(auto it = map.begin(), ite = map.end(); it != ite;)
{
  if(it->second._id == remove_id)
    it = map.erase(it);
  else
    ++it;
}

这是安全的,因为您可以删除树中的单个节点,而不会使其他迭代器失效。请注意,我没有在 for 循环头本身中增加迭代器,因为在删除节点的情况下会跳过一个元素。


† 现在,您应该已经注意到这会对 std::map 造成严重破坏。的排序,这就是key为const的原因- 所以你不能在插入元素后以任何方式影响排序。

关于c++ - map , lambda ,remove_if,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9515357/

有关c++ - map , lambda ,remove_if的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  3. ruby - ruby 中有 each_if 吗? - 2

    假设我在Ruby中有这个each循环。@list.each{|i|putsiifi>10breakend}我想循环遍历列表直到满足条件。这让我感到“不像Ruby”,因为我是Ruby的新手,是否有Ruby方法可以做到这一点? 最佳答案 您可以使用Enumerable#detect或Enumerable#take_while,取决于您想要的结果。@list.detect{|i|putsii>10}#Returnsthefirstelementgreaterthan10,ornil.正如其他人所指出的,更好的风格是先进行子选择,然后再对其

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. ruby-on-rails - rails : check if the model was really saved in after_save - 2

    ActiveRecord用于在每次调用保存方法时调用after_save回调,即使模型没有更改并且没有生成插入/更新查询也是如此。这实际上是默认行为。在大多数情况下这没问题。但是一些after_save回调对模型是否实际保存的事情很敏感。有没有办法确定模型是否实际保存在after_save中?我正在运行以下测试代码:classStage 最佳答案 ActiveRecordusetocallafter_savecallbackeachtimesavemethodiscalledevenifthemodelwasnotchangedan

  7. ruby - 你会如何在 Ruby 中表达成语 "with this object, if it exists, do this"? - 2

    在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中

  8. ruby - 在 Ruby 的 if 语句中检查 bash 命令 - 2

    如何在Ruby的if语句中检查bash命令的返回值(true/false)。我想要这样的东西,if("/usr/bin/fswscell>/dev/null2>&1")has_afs="true"elsehas_afs="false"end它会提示以下错误含义,它总是返回true。(irb):5:warning:stringliteralincondition正确的语法是什么?更新:/usr/bin/fswscell寻找afs安装和运行状态。它会抛出这样的字符串,Thisworkstationbelongstocell如果afs没有运行,命令以状态1退出 最

  9. ruby - 在 ruby​​ 中使用 .try 函数和 .map 函数 - 2

    我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法

  10. ruby - 变量赋值后的 if 语句 - 有多常见? - 2

    我最近与一位同事讨论了以下Ruby语法:value=ifa==0"foo"elsifa>42"bar"else"fizz"end我个人并没有看到太多这种逻辑,但我的同事指出,这实际上是一种相当普遍的Rubyism。我试着用谷歌搜索这个主题,但没有找到任何文章、页面或SO问题来讨论它,这让我相信这可能是一种非常实际的技术。然而,另一位同事发现语法令人困惑,而是将上面的逻辑写成这样:ifa==0value="foo"elsifa>42value="bar"elsevalue="fizz"end缺点是value=的重复声明和隐式elsenil的丢失,如果我们想使用它的话。这也感觉它与Ruby

随机推荐