Каков наилучший способ использовать тип C uuid_t в качестве ключа в std :: map? - PullRequest
5 голосов
/ 20 ноября 2011

Это подходящий способ предоставления уникальных ключей на карте? Другими словами, ключ создается из уникального значения, содержащегося в uuid, или из указателя на структуру uuid_t? Побочный вопрос, есть ли более эффективный контейнер, когда меня не интересует порядок по ключам внутри контейнера?

#include <uuid/uuid.h>

int main(int argc, char **argv)
{    
   std::map<uuid_t,int> myMap;         

   uuid_t id1;
   uuid_t id2;

   uuid_generate( (unsigned char *)&id1 );  
   uuid_generate( (unsigned char *)&id2 );

   myMap[id1] = 5;
   myMap[id2] = 4;

}

Ответы [ 3 ]

5 голосов
/ 20 ноября 2011

Полагаю, лучший способ использования сторонних C-структур - это использовать их через дружественные функции.Поэтому, если вы хотите использовать uuid_t в STL, я бы посоветовал вам создать какой-то интерфейс / оболочку C ++ для этой структуры, например

struct Uuid {
  uuid_t uuid;
  Uuid(const Uuid &other) { uuid_copy(uuid, other.uuid); }
  Uuid(const uuid_t other_uuid) { uuid_copy(uuid, other_uuid); }
  void generateInplace() { uuid_generate(uuid); }
  static Uuid generate() { Uuid wrapped; uuid_generate(wrapped.uuid); return wrapped; }
  bool operator<(const Uuid &other) { return uuid_compare(uuid, other.uuid) < 0; }
  bool operator==(const Uuid &other) { return uuid_compare(uuid, other.uuid) == 0; }
  // ...
};

. Это должно скрывать от вас тот факт, что uuid_tструктура, но указатель на массив (то есть typedef unsigned char uuid_t[16]).

Примечание: существует расширенная версия библиотеки uuid

3 голосов
/ 20 ноября 2011

Контейнеры STL всегда содержат копии объекта, и это также относится к ключам карты.

Самый простой способ поддержать это - использовать собственный компаратор для карты.

struct UUIDComparator
{
    bool operator()(const uuid_t &a, const uuid_t &b)
    {
        //compare and return a < b
    }
};
std::map<uuid_t, int, UUIDComparator> map;

Другим немного спорным решением было бы преобразовать uuid_t в std::pair<uint64_t, uint64_t>, поскольку оба типа имеют ширину 128 бит и, AFAICT, совместимы с компоновкой. И std::pair могут непосредственно использоваться в качестве ключей карты.

std::map<std::pair<uint64_t, uint64_t>, int, UUIDComparator> map;
1 голос
/ 30 января 2013

Проще: uuid_unparse (...) преобразует его в символ * (длиной 37 символов), который затем можно обернуть строкой вокруг ...

...