Перегрузить пользовательский компаратор в std :: map

Я пытаюсь решить Эта проблема. Я придумал это решение:

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

Как видно, это не компилируется: StockTicker::stocksDict не является статическим членом Теперь я не могу сделать это так, потому что мне может потребоваться несколько экземпляров StockTicker учебный класс.

std::map использует строгое определение параметра функции компаратора (std::map будет только передавать ключи для сравнения), поэтому я не могу перегрузить его, чтобы передать ссылку на текущий экземпляр StockTicker класс (который я мог бы использовать, чтобы получить доступ к 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() а также StockTicker::top() методы:
error: '((StockTicker*)this)->StockTicker::stocksTicker' does not have class type,

Я тоже пробовал кучу других вещей (например, объявление метода публичного сравнения в StockTicker сам класс и пытается передать указатель на функцию std::map, Это также не удалось; StockTicker::stocksTicker объявляется раньше, чем метод компаратора, и компилятор жалуется).

Любые идеи о том, как это исправить?

0

Решение

 std::map<std::string, stockDictType::iterator, Comparator> stocksTicker(Comparator(stocksDict));

это определяет функцию-член с именем stocksTicker это занимает stocksDict аргумент типа Comparator и возвращает std::map,

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

Это определяет переменную-член stocksTicker который по умолчанию инициализируется с Comparatorкоторый, в свою очередь, был инициализирован переменной-членом stocksDict,

Я полагаю, вы хотите второй.

Ваш синтаксис был на полпути между ними. Какой бы компилятор ты не запутал.

Живой пример

Вам следует StockTicker(StockTicker &&)=delete а также StockTicker& operator=(StockTicker &&)=delete, поскольку карты, содержащие ссылки на содержащий их класс, небезопасны для перемещения или копирования.

Создать эффективный ход здесь сложно. Я подозреваю, что соединение узлов C ++ 17 может сделать это возможным. Возможно, вам придется встроить std::shared_ptr<stocksDict*> (да, общий указатель на указатель), и использовать .key_comp пересаживать stocksDict в цель.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]