Итак, у меня есть простой код
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 есть исключения, которые я могу хранить на карте или нет.
Нет потому что 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;
// ...
Конечно, это возможно. Это недостающая функция 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);
}