将自定义比较器重载到std :: map

时间:2017-03-31 15:49:34

标签: c++ c++11 overloading stdmap custom-compare

我正在努力解决this problem。我提出了这个解决方案:

typedef unordered_map<string, double> stockDictType;

class StockTicker {
  class Comparator {
  public:
    inline bool operator() (const string &a, const string &b) const {
      return stocksDict.at(a) < stocksDict.at(b);
    }
  };

  stockDictType stocksDict;

  map<string, stockDictType::iterator, Comparator> stocksTicker; // this is where I need a custom comparator method

  int tickerSize;

public:
  StockTicker(int k): tickerSize(k) {}

  // some other methods
};

很明显,这无法编译:{{1​​}}不是静态成员。现在我无法做到这一点,因为我可能需要StockTicker::stocksDict类的多个实例。

StockTicker使用严格的比较器函数参数定义(std::map只会传入要比较的键),所以我不能重载它来传递对当前实例的引用std::map课程(我可以通过公共获取者访问StockTicker

我从this SO questionsubsequent answer获取灵感来执行此操作:

StockTicker::stocksDict

这也不会编译。我在typedef unordered_map<string, double> stockDictType; class StockTicker { class Comparator { public: stockDictType &_stockDictRef; explicit Comparator(stockDictType &stocksDict): _stockDictRef(stocksDict) {} inline bool operator() (const string &a, const string &b) const { return _stockDictRef.at(a) < _stockDictRef.at(b); } }; stockDictType stocksDict; map<string, stockDictType::iterator, Comparator> stocksTicker(Comparator{stocksDict}); int tickerSize; public: StockTicker(int k): tickerSize(k) {} void addOrUpdate(string name, double price) { stocksDict[name] = price; stocksTicker.at(name) = stocksDict.find(name); } vector<stockDictType::iterator> top() { vector<stockDictType::iterator> ret(tickerSize); auto it = stocksTicker.begin(); for(int i = 0; i < tickerSize; i++, it++) ret[i] = it->second; return ret; } }; StockTicker::addOrUpdate()方法中获得此kind of errorStockTicker::top()

我也尝试了其他一些东西(比如在error: '((StockTicker*)this)->StockTicker::stocksTicker' does not have class type类中声明一个公共比较器方法,并尝试将它的函数指针传递给StockTicker。这也失败了; {{ 1}}在比较器方法之前声明并且编译器抱怨)。

关于如何解决此问题的任何想法?

1 个答案:

答案 0 :(得分:2)

stocksTicker

这定义了一个名为stocksDict的成员函数,该函数接受类型Comparator的{​​{1}}参数并返回std::map

std::map<std::string, stockDictType::iterator, Comparator> stocksTicker{Comparator{stocksDict}};

这定义了一个成员变量stocksTicker,默认情况下,使用Comparator进行初始化,然后使用成员变量stocksDict对其进行初始化。

我假设你想要第二个。

你的语法在两者之间。无论你有什么编译器都对此感到困惑。

the documentation

您应该StockTicker(StockTicker &&)=deleteStockTicker& operator=(StockTicker &&)=delete,因为包含对其包含类的引用的地图无法移动或复制。

在这里产生有效的举动是棘手的。我怀疑C ++ 17节点拼接可能会让它成为可能。您可能必须嵌入std::shared_ptr<stocksDict*>(是,指针的共享指针),并使用.key_comp重置目标中的stocksDict