Мне нужно, чтобы получить самый маленький элемент в std::map
, Я знаю, что есть много доступной документации; Однако я не могу заставить кого-либо работать.
У меня есть две карты, bid
а также ask
оба из которых являются свойствами Book
учебный класс. Каждый представляет собой карту очередей. Каждая из этих очередей содержит Order
объекты (которые имеют различные свойства, такие как price
, volume
, так далее.). У меня есть функция-член update
которая получает лучшую ставку, лучшую цену и спред:
void update(void)
{
unsigned long long highest_bid, lowest_ask = 0;
for (std::map<unsigned long long, queue<Order>>::iterator it = this->bid.begin(); it != this->bid.end(); ++it)
{
highest_bid = it->first;
}
// best ask code here
this->bestBid = highest_bid;
this->bestAsk = lowest_ask;
this->spread = labs(this->bestAsk - this->bestBid);
}
Где код запроса, я попробовал следующее:
lowest_ask = this->ask.begin()->first;
Это компилируется, но когда я отлаживаю, это приводит к ошибке подтверждения (которую я прочитал по другим вопросам здесь и не могу понять):
Expression: map/set iterator not dereferencable
Я пробовал обратную итерацию:
for(std::map<unsigned long long, queue<Order>>::reverse_iterator rit = this->ask.rbegin(); rit != this->ask.rend(); ++rit)
{
lowest_ask = rit->first;
}
Что хорошо компилируется и отлаживается, но lowest_ask
всегда 0, что неправильно. Когда я делаю это в отладчике, он не останавливается, пока не достигнет нуля.
Я пытался поменять местами итераторы:
for(std::map<unsigned long long, queue<Order>>::reverse_iterator rit = this->ask.rend(); rit != this->ask.rbegin(); ++rit)
{
lowest_ask = rit->first;
}
Это скомпилировано нормально, но еще раз бросил ошибку отладочного утверждения.
Я мог бы продолжать и продолжать то, что я пробовал, но этот вопрос уже слишком сложен. Я просто не понимаю, почему я не могу просто сделать то, что я сделал в начале (lowest_ask = this->ask.begin()->first
).
Заранее большое спасибо.
Возможно ли, что вы «царапаете ухо локтем»? Я хочу сказать, что итерация по карте и постоянное присвоение одной и той же переменной кажется ненужной тяжелой работой.
Если вам нужен доступ к первому элементу на карте (или к последнему элементу на карте), тогда start () (или rbegin ()) — это все, что вам нужно.
std::map <int, int> themap;
themap[4] = 1;
themap[2] = 2;
themap[1] = 3;
themap[6] = 4;
themap[5] = 5;
themap[7] = 6;
if (!themap.empty())
{
std::cout << "item[" << themap.begin()->first << "] = " << themap.begin()->second << std::endl;
std::cout << "item[" << themap.rbegin()->first << "] = " << themap.rbegin()->second << std::endl;
}
единственное время, когда вам нужно быть осторожным с началом и rbegin, это когда ваша карта пуста
Я думаю, что вам просто нужно проверить, что ваши контейнеры не пустые, чтобы begin()
а также rbegin()
вернуть что-то значимое (Определенно).
Попробуй это:
void update(void)
{
if(bid.empty() || ask.empty())
return;
// best ask code here
this->bestBid = bid.rbegin()->first;
this->bestAsk = ask.begin()->first;
this->spread = labs(this->bestAsk - this->bestBid);
}
Это не «сложно»; он просто принимает некоторые стандартные меры отладки
#include <map>
#include <iostream>
#include <algorithm>
#include <random>
#include <string>
#include <queue>namespace mock {
using Order = std::string;struct Book {
using key_type = unsigned long long;
using order_queue_type = std::queue<Order>;
using property_type = std::map<key_type, order_queue_type>;
property_type bids, asks;void diagnose(const property_type& prop) {
for (auto it = prop.cbegin(); it != prop.cend(); ++it) {
std::clog << "\t" << it->first << '\n';
}
}
void diagnose() {
std::clog << "bids:" << '\n';
diagnose(bids);
std::clog << "asks:" << '\n';
diagnose(asks);
}
Book() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<key_type> ba_dist(0, 1000);
std::uniform_int_distribution<std::size_t> len_dist(0, 10);
auto prop_gen = [&] (property_type& prop) {
auto count = len_dist(gen);
for (std::size_t i = 0; i < count; ++i) {
auto val = ba_dist(gen);
auto pair = prop.emplace(val, order_queue_type());
if (!pair.second) {
std::clog << val << " already present" << '\n';
}
}
};
prop_gen(bids);
prop_gen(asks);
}
};
}int main() {
mock::Book book;
book.diagnose();
}
Вместо генератора по моему Book
ctor, используйте ваши процедуры инициализации, конечно же, и ваши Order
тип.