Каков наилучший способ использовать тип C uuid_t в качестве ключа в std::map?
Это подходящий способ предоставления уникальных ключей на карте? Другими словами, ключ сделан из уникального значения, содержащегося в 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 ответа
Я думаю, что лучший способ использования сторонних 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
Контейнеры 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;
Проще: uuid_unparse(...) преобразует его в символ * (длиной 37 символов), который затем можно обернуть строкой...