【问题标题】:Joining two containers of objects, adding elements if already present加入两个对象容器,添加元素(如果已经存在)
【发布时间】:2016-08-16 12:37:16
【问题描述】:

我有两个容器类型的对象:

struct Element
{
    int A;
    int B;

    Element operator+=(const Element& rhs)
    {
        if(A != rhs.A)
            throw std::runtime_error("Not like this");

        B += rhs.B;
        return *this;
    }
};

inline Element operator+(Element lhs, const Element& rhs)
{
    lhs += rhs;
    return lhs;
}

现在我想加入这两个容器,如下所示:

  • 如果目标容器中没有其他元素具有相同的值 A,则插入它
  • 如果目标容器中的另一个元素具有相同的值 A,则将已经存在的元素和新元素相加

我想知道是否有一个优雅的解决方案(比只有两个向量并循环它们更短)使用与向量不同的容器来解决这个问题。

【问题讨论】:

  • 您的容器是否经常被修改?您是否经常需要按顺序迭代它们?是否应该切换容器取决于这些问题。
  • 你错过了return *this; operator +=

标签: c++ stl c++14


【解决方案1】:

如果使用std::map<int, Element> 类型的映射,其中的键是A 值?

std::map<int, Element>  m1;
std::map<int, Element>  m2;

// add something in m1 e/o m2

for ( auto const & e : m2 )
 {
   m1[e.first] += e.second;
 }

关键是m1[e.first]返回一个对m1中的元素的引用,如果存在键e.first,或者创建它,如果不存在,返回对新创建元素的引用。

重要的一点是元素的默认构造函数为新创建的元素的A 值赋予一个特殊值,其含义是“从添加的Element 中吸收A 值”。

但是如果它仅用作地图的键,您可以放弃Element 中的A 值。

【讨论】:

  • 旁注:我相信即使对于像上面的 for 循环这样的单语句主体,也可以包含显式大括号,特别是在 SO 答案的情况下,其中答案的内容是容易被初学者使用(即,重新加强不易出错的练习)。有关讨论,请参见例如this SE Programmer's Q&A.
  • 根据cplusplus.com/reference/map/map/operator[],map 的 operator[] 不返回 const 引用,而只是返回一个引用。
  • @MrZ - 在这种情况下,您需要一个引用,而不是 const 引用,因为您必须修改它(m1 的元素)。 m2 (e) 的元素可以是 const,因为你只需要阅读它
  • 这就是为什么我指的是您的声明“将 const 引用返回给新创建的元素”,但也许我误解了您的回答。
  • @MrZ - 哦!你是对的:是一个错误。更正;谢谢。
猜你喜欢
  • 2019-10-21
  • 1970-01-01
  • 2012-09-12
  • 2019-12-23
  • 2020-12-10
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
相关资源
最近更新 更多