考虑

 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.
}


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

关于c++ - 如何优化C++类容器的加法运算符?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41830729/

10-09 06:40