Можно ли хранить QColor в QMap в качестве ключа

Итак, у меня есть простой код

QMap<QColor, int> colors;
for(int w = 0; w < image.width(); ++w)
for (int h = 0; h < image.height(); ++h)
colors[QColor::fromRgb(image.pixel(w,h))]++;

Сообщение об ошибке

нет совпадения для оператора<‘(типы операндов’ const QColor ‘и’ const QColor ‘).

Так, qMapLessThanKey безуспешно пытается создать экземпляр для сравнения двух цветов, и это невозможно.

Вопрос: Можно ли хранить QColor в QMap в качестве ключа в качестве значения, а не по ссылке?

Просто любопытно. Я знаю, как написать то, что я хочу по-другому. Но мне кажется странным, что в QT есть исключения, которые я могу хранить на карте или нет.

3

Решение

Нет потому что QColor не обеспечивает operator<, который требуется от QMap«s Key тип:

Тип ключа QMap должен предоставить operator<() указав общий заказ.

Можно было бы определить operator< за QColor сами, но я бы не советовал, потому что я не уверен, что это должно быть определено.

Я бы порекомендовал просто использовать std::map с пользовательским компаратором (третий аргумент шаблона) вдоль строк:

struct color_compare {
bool operator()(QColor const&, QColor const&) { /* ... */ }
};

std::map<QColor, Value, color_compare> map;
// ...
5

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

Конечно, это возможно. Это недостающая функция Qt. Вы можете самостоятельно реализовать оператор сравнения, сравнивая значения R, G, B, A лексикографически:

// https://github.com/KubaO/stackoverflown/tree/master/questions/qmap-qcolor-32512125
#include <QtGui>

bool operator<(const QColor & a, const QColor & b) {
return a.redF() < b.redF()
|| a.greenF() < b.greenF()
|| a.blueF() < b.blueF()
|| a.alphaF() < b.alphaF();
}

int main() {
Q_ASSERT(QColor(Qt::blue) < QColor(Qt::red));
Q_ASSERT(QColor(Qt::green) < QColor(Qt::red));
Q_ASSERT(QColor(Qt::blue) < QColor(Qt::green));
Q_ASSERT(! (QColor(Qt::red) < QColor(Qt::red)));
QMap<QColor, int> map;
map.insert(Qt::red, 0);
map.insert(Qt::green, 1);
map.insert(Qt::blue, 2);
Q_ASSERT(map.size() == 3);
Q_ASSERT(map.cbegin().key() == Qt::red);
Q_ASSERT((map.cbegin()+1).key() == Qt::green);
Q_ASSERT((map.cbegin()+2).key() == Qt::blue);
}
1

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