Я повторно реализую std::map
. Мне нужно убедиться, что ключ любого типа данных (базовый или определяемый пользователем) будет работать с ним. Я объявил класс Map как шаблон, который имеет два параметра для ключа и значения. Мой вопрос: если мне нужно использовать строку в качестве типа ключа, как я могу перегрузить операторы ‹ и > только для ключей строкового типа?? В специализации шаблона мы должны специализировать весь класс с помощью тип, который нам нужен, насколько я понимаю.
Можно ли как-то сделать это лучше?? Что, если я добавлю отдельный класс Key и использую его в качестве типа шаблона для Key?
Пользовательский класс как параметр шаблона
Ответы (2)
Вы должны выделить сравнение как тип, как это делает обычный std::map
. То есть иметь служебный класс less_compare
:
template <typename T>
struct less_compare
{
bool operator()(const T& pLhs, const T& pRhs) const
{
return pLhs < pRhs;
}
};
А потом:
template <typename Key, typename Value, typename Compare = less_compare<Key> >
class map
{
// ...
private:
Compare mCompare;
};
И чтобы сравнить два значения, выполните: if (mCompare(someThing, someOtherThing))
, что будет верно, если someThing
будет "меньше" someOtherThing
. Обратите внимание, что этот факторинг также допускает определяемые пользователем сравнения (именно поэтому в кавычках указано «меньше»). Это известно как дизайн, основанный на политике.
И теперь вы можете специализировать только класс less_compare
для C-струн. (А также предоставить greater_compare
и род.)
Имейте в виду, если это не для обучения, вы не должны реализовывать свою собственную карту. Также обратите внимание, что std::string
уже перегружен operator<
.
<map>
и используйте std::map
.) Тем более, что то, что уже сделано, было (и есть) сильно оптимизировано и протестировано.
- person GManNickG; 20.05.2010
Вы также можете использовать типовые черты. Это даст вам основу для решения возможных будущих различий между типами.