TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.34K subscribers
Post #172 1.35K
​Что нужно возвращать из оператора присваивания? Ч2

В прошлом посте мы поговорили о том, что точно не нужно возвращать из оператора присваивания, потому что это нарушает его семантику. У нас остались для рассмотрения 3 варианта: void, неконстантная ссылка и константная ссылка. Их всех корректно использовать, только какие-то будут накладывать определенные ограничения.

Самый банальный пример - цепочка присваивания. Это конструкция вида: a = b = c;. Если честно, то никогда такой штукой не пользовался. Однако надо учитывать, что кому-то могут понадобиться такие конструкции. Очевидно, что если оператор присваивания будет возвращать void, цепочкой присваиваний нельзя будет пользоваться для такого класса.

Ну или может быть вы хотите присвоить значение объекту и потом для конкретно этого объекта вызвать метод. Например так:

(obj = temp_obj).foo();


Если метод вернет void, то такая штука просто не скомпилируется. Это кстати довольно удобно делать в условиях. Типа того:

if ((obj = SomeFunc()).isValid()) {...}


Мы хотим использовать результат SomeFunc дальше по коду, поэтому хотим присвоить его именованной переменной. Но и хотим сразу проверить, валидный ли объект. Эти операции удобно делать сразу налету в условии. А если оператор вернет void, то этим удобным инструментом нельзя будет пользоваться. Конечно, этот пример скорее для перемещающего присваивания, но суть та же.

Теперь осталось разобраться с константностью. На самом деле даже далеко уходить не надо. Возьмем кейс с условием. В случае константной ссылки мы не сможем выполнять неконстантные методы, которые собственно и нельзя вызывать у константных ссылок. Потому что подразумевается, что константная ссылка - read-only сущность и нам запрещено через нее изменять объект, на который указывает ссылка. Это несколько ограничивает наши возможности.

Ну и остается только неконстантная ссылка. У нее нет side эффектов семантически и она позволяет выполнять все операции, которые нам были недоступны выше.

Однако помимо всего прочего есть еще одна причина делать возвращаемое значение неконстантной ссылкой. Такую форму и семантику реализуют операторы присваивания для тривиальных типов. Все мы в нашем плюсовом юношестве наигрались с интами и флотами и просто на интуитивном уровне понимаем, как для них все работает. И очень круто, когда пользовательский класс перенимает такое же поведение. Потому что пользователю будет намного проще работать с таким классом. Меньше времени на понимание работы с объектом и памяти на сохранение информации о нем - больше производительность программиста. Это конвертируется в денежку. Всем это выгодно.

Поэтому без особой надобности не изменяйте этот де-факто стандартный вид возвращаемого значения. Вы сможете юзать весь объем возможностей использования класса и сделаете его проще для понимания.

Use all of your abilities. Stay cool.

#cppcore
  • 👍 15
  • 🔥 3
  • ❤ 2
More from @grokaemcpp
  1. Oct 17, 2026Оптимистичные и пессимистичные блокировки #опытным Концепция блокировок уходит далеко за п…
  2. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  3. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  4. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  5. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  6. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →