2013-10-08 3 views
2

Я попробовал программу сэмпла STL, используя «карту».Где находится оператор «<», используемый в этом примере?

http://ideone.com/LB8xvh

#include <iostream> 
#include <map> 
#include <cstring> 
using namespace std; 

class ItemName 
{ 
    char name[80]; 
public: 
    ItemName(char *s) { strcpy(name, s); } 
    char *get() { return name; } 
}; 

bool operator<(ItemName a, ItemName b) 
{ 
    return strcmp(a.get(), b.get()) < 0; 
} 

class ItemObj 
{ 
    char str[80]; 
public: 
    ItemObj(char *s) { strcpy(str, s); } 
    char *get() { return str; } 
}; 

char itemdata[][80] = { 
    "potion", "heal HP", 
    "key", "unlock a door", 
    "lamp", "light", 
}; 


int main() { 
    map<ItemName, ItemObj> items; 

    for(int i=0; i<3; i++) { 
     items.insert(
       pair<ItemName, ItemObj>(
        ItemName(itemdata[i*2]), 
        ItemObj(itemdata[i*2+1]))); // ***** pair ***** 

    } 

    map<ItemName, ItemObj>::iterator p; 

    char str[80]; 
    const int kMaxLoop = 5; 
    int nLoop = 0; 
    while(nLoop < kMaxLoop) { 
     cout << "> "; 
     cin >> str; 
     p = items.find(str); 
     if(p != items.end()) { 
      cout << p->second.get() << endl; 
     } else { 
      cout << "unknown item." << endl; 
     } 
     nLoop++; 
    } 

    return 0; 
} 

В этом примере, я не совсем уверен, где оператор "<" используется. Если я прокомментирую определение оператора «<», я получаю много ошибок.

+2

Упростите себя и используйте 'std :: string'. Строки C - это просто дополнительная работа, которая не принесет никакой пользы. – chris

+0

Благодарим вас за советы. Я запомню это. – sevenOfNine

ответ

5

имеет параметр, указывающий, как сравнивать элементы на карте (необходимо, потому что карта всегда сохраняет свое содержимое, отсортированное по порядку по ключу). По умолчанию это std::less<T>.

std::less<T>, в свою очередь, проведет сравнение с использованием operator<.

Вы можете создать карту объектов, для которых operator< не определен, но для этого вам необходимо явно указать функцию сравнения/функтор.

Это сказало: ваши ItemData и ItemObj оба действительно просто делают то, что уже могут сделать std::string. Вы могли бы уменьшить большую часть приведенного выше кода примерно так:

std::map<std::string, std::string> items{ 
    { "potion", "heal HP"  }, 
    { "key", "unlock a door" }, 
    { "lamp", "light"   } 
}; 
+0

Большое спасибо, Джерри Коффин. Я мог хорошо понять, как это работает. Кроме того, я ценю, что вы показываете мне альтернативный способ использования std :: string. – sevenOfNine

+0

Это сработало! Спасибо. http://ideone.com/fSfdZK – sevenOfNine

5

Используется для внутреннего использования map для размещения и поиска записей. В противном случае find пришлось бы сравнить ключ, который вы поставляете, буквально каждый отдельный вход по одному, и вы не могли бы перебирать карту в ключевом порядке.

В принципе, map s эффективно хранить элементы на заказ. Для этого они должны иметь какой-то способ узнать, что такое ,, и они это делают, позвонив по номеру operator< (если не указано иное).

+0

Это не совсем правильно. ['std :: map'] (http://en.cppreference.com/w/cpp/container/map), который по умолчанию является' std :: less 'использует' operator <', следовательно вы можете создать 'std :: map', который не требует * operator <'. –

+0

@ DanielFrey Спасибо. Обновлено. –

+0

Большое спасибо, Дэвид Шварц и Даниэль Фрей. Я вижу, что на карте используется оператор «<» внутри. Кроме того, я буду изучать std :: less . – sevenOfNine

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