Перегрузка доступа к скобкам и назначение C ++

StackOverflow https://stackoverflow.com/questions/1618524

  •  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), а затем возвращает ссылку на этот новый объект, что позволяет вызывающей стороне присвоить объекту значение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top