Как добавить определение оператора в существующую структуру из заголовочного файла? - PullRequest
5 голосов
/ 23 сентября 2019

Я разрабатываю SNMP Agent в Windows.В заголовочном файле snmp.h есть struct, который определяет идентификатор OID для значения, и определение для него следующее:

typedef struct {
  UINT   idLength;
  UINT * ids;
} AsnObjectIdentifier; 

Я хочу использовать это AsnObjectIdentifier какключ к unordered_map, но определение struct не перегружает оператор ==, что приводит меня к вопросу, возможно ли добавить перегрузку оператора к уже определенному struct или мне придетсяпросто мой пользовательский struct, обертывающий переменную AsnObjectIdentifier.

Ответы [ 2 ]

4 голосов
/ 23 сентября 2019

Вы можете просто использовать пользовательский функтор в объявлении unordered_map.

Действительно, unordered_map предоставляет для этого специальные аргументы шаблона.

Примечание : вам нужно предоставить функтор для вычисления значения хеша также для unordered_map.

template<
    class Key,
    class T,
    class Hash = std::hash<Key>,   // <----- You need hash for Key
    class KeyEqual = std::equal_to<Key>, // <---- Equal Functor
    // ...

Просто определите ваш функтор в соответствии с логикой вашей программы.Что-то вроде:

struct AsnObjectIdentifierHasher {
  std::size_t operator()(const AsnObjectIdentifier&) const noexcept;
};

struct AsnObjectIdentifierComparator {
  bool operator()(const AsnObjectIdentifier&, 
                  const AsnObjectIdentifier&) const noexcept;
};

template <typename T>
using HashMap = std::unordered_map<AsnObjectIdentifier, 
                                   T, 
                                   AsnObjectIdentifierHasher, 
                                   AsnObjectIdentifierComparator>;

Я настоятельно не рекомендую использовать free-function для реализации арифметических и логических операторов (особенно, когда интерфейс STL обеспечивает настройку посредством аргументов шаблона), Функторы (функциональные объекты) обеспечивают лучший код изоляции и позволяют избежать проблем с областью действия (например, ADL).

4 голосов
/ 23 сентября 2019

Да, вы можете определять операторы вне класса:

bool operator==(AsnObjectIdentifier const& lhs, AsnObjectIdentifier const& rhs)
{
    return /* whatever */;
}

В качестве альтернативы вы можете определить объект пользовательской функции равенства и передать его четвертому параметру шаблона unordered_map.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...