如何优化 C++ class 容器的加法运算符?

How can an addition operator for a C++ class container be optimized?

考虑

 class abc
   {
     public:
     map<int,double> data;

     abc(map<int,double> && in):data(std::move(in)){}
     abc operator + (const abc & in)
     {
     auto tmp = data;
       for( auto & itr : in.data)
          tmp[itr.first] += itr.second;
      return abc(std::move(tmp));
     }
   };

我想更好的实现可能是

     abc operator + (const abc & in)
     {
      auto &tmp1 = (data.size() > in.data.size() ? data : in.data);
      auto &tmp2 = (data.size() > in.data.size() ? in.data : data);
      auto tmp = tmp1;
       for( auto & itr : tmp2)
          tmp[itr.first] += itr.second;
      return abc(std::move(tmp));
     }

我想要实现的是,如果我有一个声明,例如,

    S = A+B+C+D+E

并假设 BCD 为空成本应与

相同
   S = A+E

如果 abc 类型为零,我基本上不想承担费用。有办法实现吗?

我认为你会做得更好:

 abc operator + (abc lhs, const abc& rhs)   // Note 'lhs' by value.
 {
     for(const auto & val : rhs.data)
         lhs.data[val.first] += val.second;
     return lhs;                                  // Rely on NRVO 
 }

更喜欢按值获取参数的原因是,如果它是临时的(例如,A + B 的结果),则不需要副本。编译器可以直接传递临时文件。

编辑 WhiZTiM 建议的代理会更有效率,因为它将所有事情推迟到最后。它依赖于在完整表达式结束之前临时对象不会被销毁的事实。

struct Proxy
{
    std::vector<const abc*> values;

    operator abc() {
        assert(values.size() > 2);
        abc result = *(values.back());  // Can't avoid one copy.
        values.pop_back();
        for (const auto& v : values)
            for (const auto& key_value : v->data)
                result.data[key_value.first] += key_value.second;

        return result;
     }
};

Proxy operator +(const abc &lhs, const abc& rhs) {
    Proxy result;
    result.values.push_back(&lhs);
    result.values.push_back(&rhs);
    return result;
}

Proxy operator +(Proxy lhs, const abc& rhs) {
    lhs.values.push_back(&rhs);
}
Proxy operator +(const abc& lhs, Proxy rhs) {
    rhs.values.push_back(&lhs);
}
Proxy operator +(Proxy lhs, const Proxy& rhs) {
    // implementation left as an exercise for the reader.
}

注意:以上未公开给编译器。