Перегрузка доступа к скобкам и назначение C ++
-
06-07-2019 - |
Вопрос
Я пишу хэш-таблицу для своего класса data structs, и я хотел бы добавить немного синтаксического сахара в свою реализацию.
template <typename HashedObj, typename Object>
Object & Dictionary<HashedObj, Object>::operator[](HashedObj & key)
{
return items.lookup(key);
}
Это прекрасно работает, когда я делаю что-то вроде cout << дикт ["мой ключ"]. Но как я могу выполнить присваивание с помощью скобок? Что -то вроде:
dict["mykey"] = "something";
И нет, это не часть моего домашнего задания (без каламбура), я просто хочу выучить C ++ немного лучше.
Решение
Непонятно, о чем именно вы здесь спрашиваете.Представленный вами код уже поддерживает назначение.Просто сделайте это, и at заработает (или, по крайней мере, оно должно скомпилироваться).Не имеет абсолютно никакого значения, с какой стороны оператора присваивания вы перегружены []
используется на.Он будет работать точно так же в левой части (LHS), как и в правой части (RHS) присваивания (или как операнд <<
, как в вашем первоначальном посте).Ваш []
возвращает ссылку на Object
, и затем фактическое присвоение обрабатывается оператором присваивания вашего Object
тип, означающий, что []
сам по себе на самом деле не участвует в фактическом задании.
Реальный вопрос здесь заключается в том, как вы хотите, чтобы ваш []
действовать в определенных особых случаях.Что произойдет, если вашего ключа нет в таблице?Ссылка на что Object
это ваш lookup
собираетесь вернуться в этом случае?
Это невозможно понять из того, что вы опубликовали.Я вижу, что это возвращает ссылку, поэтому возвращаю NULL
об этом не может быть и речи.Вставляет ли он новое, пустое Object
для данного ключа?Если это так, то вам не нужно ничего делать.Ваш []
уже полностью готов к использованию на LHS устройства.(Вот как []
в std::map
работает, кстати)
В случае, если ваш lookup
возвращает ссылку на специальный "охранник" Object
, вы должны предпринять особые шаги.Вероятно, вы не хотите ничего назначать объекту "guard", поэтому вам нужно каким-то образом "отключить" его оператор присваивания, и все готово.Остальное должно работать как есть.
Если ваш lookup
генерирует исключение в случае несуществующего ключа, затем вы должны решить, является ли это тем, что вы хотите, когда []
используется в LHS задания.Если это так, то вам не нужно ничего делать.Если нет, то потребуется дополнительная работа...
Итак, опять же, что произойдет, если вы передадите несуществующий ключ lookup
?
P.S.Кроме того, обычно имело бы больше смысла объявлять []
(и lookup
) с любым const HashedObj&
параметр или просто HashedObj
параметр.Неконстантная ссылка, как в вашем примере, выглядит странно и может привести к проблемам в некоторых (на самом деле, в большинстве) случаев.Я удивлен, что теперь у тебя это работает...
Другие советы
Вам нужно перегрузить это 2 раза. Тот, который будет const
, который будет частью data access
, и тот, который будет возвращать ссылку, которая будет действовать как & Quot; setter & Quot;.
Что вам нужно, так это функциональность, похожая на оператор перегруженной скобки в std::map
. В std::map<K,V> mymap
оператор скобок выполняет поиск и возвращает ссылку на объект, связанный с конкретным ключом. Если карта не содержит объектов, связанных с ключом, оператор вставляет новый объект в карту, используя конструктор по умолчанию.
Итак, если у вас есть mymap[someKey]
, то вызов someKey
либо вернет ссылку на значение, связанное с V
, либо создаст новый объект типа V()
, вызвав <=> ( конструктор по умолчанию V), а затем возвращает ссылку на этот новый объект, что позволяет вызывающей стороне присвоить объекту значение. Р>