2013-05-03 2 views
3

У меня есть данные, которые однозначно идентифицируются комбинацией из 3 целых чисел.Оператор сравнения для Структурный ключ в таблице карт C++

Например:
Пункт # 1: 10,20,1
Пункт # 2: 10,21,0
Пункт # 3: 0,14,13
Пункт # 4: 103,324,78

Моя структура:

struct structureKeyID 
{ 
    int keyA; 
    int keyB; 
    int keyC; 

    // Comparison operator for table sorting. 
    bool operator<(const structureKeyID& param) const 
    { 
     if (keyA < param.keyA) return true; 
     if (keyB < param.keyB) return true; 
     if (keyC < param.keyC) return true; 
     return false; 
    } 
}; 

map <structureKeyID, classDataRecord> tableRecords; 

Я нашел, если добавить ключ (0,0,1):

structureKeyID keyID1; 
keyID1.keyA = 0; 
keyID1.keyB = 0; 
keyID1.keyC = 1; 
tableRecords[keyID1] = <data>; 

я затем проверить, если ключ (0,1,0) существует:

structureKeyID keyID2; 
keyID1.keyA = 0; 
keyID1.keyB = 1; 
keyID1.keyC = 0; 
if (tableRecords.find(keyID2) != tableRecords.end()) 

Тогда я получаю сообщение об ошибке:

Debug Assertion Failed!
\include\xtree Line: 1268
Expression: invalid operator

В то время как, если я проверить, если ключ (0,0,2) или если ключ (10,0,2) существует, он отлично работает.

Каков правильный способ построения оператора сравнения для этой ситуации?

спасибо!

+3

Это может быть полезно http://stackoverflow.com/questions/16340680/creating-a-composite-type-from-two-enum-classes-ready-for-stl-map/16341009#16341009, который использует ' станд :: tie'. Если у вас нет C++ 11, доступен 'boost :: tie'. – hmjd

ответ

6

Попробуйте

// Comparison operator for table sorting. 
bool operator<(const structureKeyID& param) const 
{ 
    if (keyA < param.keyA) return true; 
    if (keyA > param.keyA) return false; 
    if (keyB < param.keyB) return true; 
    if (keyB > param.keyB) return false; 
    if (keyC < param.keyC) return true; 
    if (keyC > param.keyC) return false; 
    return false; 
} 

Ваша версия не определяет порядок последовательного (технический термин строгий слабый порядок), так как с функцией сравнения можно было бы иметь < < B C < , поэтому std::map путается.

+0

Это имеет смысл! 3 строки кода, и он отлично работает, спасибо! – user2347261

8

Самой простая реализация менее чем сравнения, удовлетворяющее строгого слабого упорядочение с std::tie, доступным в заголовке <tuple>:

bool operator<(const structureKeyID& param) const 
{ 
    return std::tie(keyA, keyB, keyC) < std::tie(param.keyA, param.keyB, param.keyC); 
} 

Это выполняет лексикографическое сравнение. Если у вас нет поддержки на C++ 11, вы можете найти эквиваленты в TR1 и Boost.

+0

У меня нет кортежа, доступного мне в этом проекте. Я ценю информацию, хотя и буду смотреть на связи в будущем. Благодаря! – user2347261

+0

Если keyA, keyB и т. Д. Были float, как это влияет на стабильность использования такой структуры, как ключ на карте? Хотя использование одного поплавка в качестве ключа карты подвержено ошибкам, является ли эта комбинация поплавков с использованием 'std :: tie' лучше? – johnbakers

Смежные вопросы