【问题标题】:Remove an element from std::list if a similar element is already present如果相似元素已经存在,则从 std::list 中删除一个元素
【发布时间】:2013-09-14 18:12:03
【问题描述】:

我的列表如下:

list<event_t*> my_list;

类 event_t 看起来像:

class event_t {

public:
  event_t(String *_session_time, String *_event_type, String *_table_name, String *_num_of_events);
  ~event_t();
   std::string table_name;
   std::string event_type;  
   pthread_mutex_t lock;
   pthread_cond_t cond;
   int num_of_events_threshold;
   double time_out; 
   int num_of_events_so_far; 
};  

如果列表中已经存在类似的对象,我想删除一个 event_t 对象。我有一个指向要删除的对象的指针。如何从列表中删除它?如果两个 event_t 对象具有相同的 table_name 和相同的 event_type,则它们是相似的。

【问题讨论】:

  • 我认为不需要指针。
  • 你说的是列表中的指针吗?
  • 是的,据我所知完全没有必要。
  • 我将不胜感激。我可能需要一个指针列表来做很多事情,这可能会改变 number_of_events 计数。如果与其他类有某种关联,那么我们肯定需要指针。

标签: c++ multithreading list class stl


【解决方案1】:

在 C++03 中你可以这样做:

struct equal {
      bool operator()(const event_t* t) {
        return *t == object_;
      } 
      event_t object_;
      equal(event_t object) : object_(object) {}
};

  event_t object;
  list<event_t*>::iterator pend = my_list.remove_if (equal(object));

我假设您已经为您的班级 event_t 定义了 operator==。如果没有,请使用此版本:

struct equal {
          bool operator()(const event_t* t) {
            return t->table_name == object_.table_name
                               && t->event_type == object_.event_type;
          } 
          event_t object_;
          equal(event_t object) : object_(object) {}
    };

在 C++0x (C++11) 中,您可以使用 lambda 函数作为 remove_if 的谓词。

event_t* object;

my_list.remove_if([object](event_t* e){ 
                  return e->table_name == toDelete->table_name 
                      && e->event_type == toDelete->event_type; 
                  });

正如其他人回答的那样:请重新考虑使用指针的想法,使用list&lt;event_t&gt; 可能会更好(如果您真的不需要指针)。然后你就可以std::list::sort 并使用std::list::unique 就可以了。

【讨论】:

  • 最好使用容器的接口而不是通用函数。 list.remove_if 会更好。
【解决方案2】:

一种方法是使用std::list::remove_if

event_t* toDelete;
// set toDelete
// Now remove all elements from the list that have the same table_name and event_type as toDelete
my_list.remove_if([toDelete](event_t* e){
                                 return e->table_name == toDelete->table_name &&
                                        e->event_type == toDelete->event_type; 
                                 });

【讨论】:

    【解决方案3】:

    您可以排序然后使用unique

    【讨论】:

    • 使用自定义比较谓词。
    • 那么 remove_if 可能会更快
    • 我错过了关于他已经有一个指向要删除的元素的指针的部分。如果没有更多的上下文,很难知道最好的选择是什么。根据更广泛的上下文,使用带有自定义比较谓词的集合可能是最佳选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    相关资源
    最近更新 更多