C++模板类operator+=重载链式调用失效问题求助
map_aligner的operator+=链式调用失效问题解决
问题背景
需为现有cpp文件实现模板类map_aligner并重载operator+=,分开调用ls += lmb;和ls += lmc;功能正常,但链式调用(ls += lmb) += lmc;仅能添加一个元素,且无法修改cpp文件。
现有cpp核心调用代码
map_aligner<std::string, std::string, string_size_less> ls; ls.add( lma ); (ls += lmb) += lmc; // 链式调用仅添加lmb,未添加lmc到原ls对象
当前operator+=实现(问题所在)
map_aligner operator+=(std::map<KEY, VALUE, COMPARE>& m){ maps_.push_back(&m); map_aligner ma = *this; return ma; }
问题原因
当前operator+=返回的是对象副本而非原对象的引用。链式调用时,(ls += lmb)返回临时副本,后续+= lmc仅作用于该副本,原对象ls并未被修改,导致最终ls只包含lma和lmb。
解决方案
修改operator+=的返回值为map_aligner&(原对象的引用),确保链式调用的每一步都作用于同一个原对象:
map_aligner& operator+=(std::map<KEY, VALUE, COMPARE>& m){ maps_.push_back(&m); return *this; }
完整修正后的头文件代码
#ifndef MAPALIGN_H #define MAPALIGN_H #include <vector> #include <map> #include <typeinfo> template<typename KEY, typename VALUE, typename COMPARE = std::less<KEY>> class map_aligner{ public: typedef typename std::map<KEY, VALUE, COMPARE>::size_type size_type; map_aligner() {} void add(std::map<KEY, VALUE, COMPARE>& m) { maps_.push_back(&m); } // 修正后的operator+=,返回引用 map_aligner& operator+=(std::map<KEY, VALUE, COMPARE>& m){ maps_.push_back(&m); return *this; } size_type count() const { return maps_.size(); } void align(){ for(int i = 0; i != (int)maps_.size(); i++ ){ std::map<KEY, VALUE, COMPARE>* first_map = maps_.at(i); for(typename std::map<KEY, VALUE, COMPARE>::iterator j = first_map->begin(); j !=first_map->end(); j++ ){ for(int h = 0; h != (int)maps_.size(); h++ ){ std::map<KEY, VALUE, COMPARE>* second_map = maps_.at(h); if(first_map != second_map && notContainsPair(second_map, j)){ second_map->insert(std::make_pair(j->first, filler_)); } } } } } bool notContainsPair(std::map<KEY, VALUE, COMPARE>* map,typename std::map<KEY, VALUE, COMPARE>::iterator it){ for(typename std::map<KEY, VALUE, COMPARE>::iterator g = map->begin(); g != map->end(); g++ ){ if(it->first != g->first){ return true; } } return false; } void set_filler(VALUE filler){ filler_ = filler; } void erase(KEY key){ for(int h = 0; h != (int)maps_.size(); h++ ){ std::map<KEY, VALUE, COMPARE>* map = maps_.at(h); // 修正:补全模板参数COMPARE typename std::map<KEY, VALUE, COMPARE>::iterator it; map->erase(key); if(typeid(it->first) == typeid(it->second)){ for(it = map->begin(); it != map->end(); it++){ if(key == it->second){ map->erase(it->first); } } } } } private: std::vector<std::map<KEY, VALUE, COMPARE>*> maps_; VALUE filler_ = VALUE(); }; #endif
额外修正说明
原头文件的erase方法中,std::map<KEY, VALUE>* map = maps_.at(h);漏写了COMPARE模板参数,会导致编译错误,已一并修正。
内容的提问来源于stack exchange,提问作者programmerGirl82
相关产品推荐
相关产品推荐

