C возвращает непосредственно из operator<<

#c #operator-overloading #ostream

#c #оператор-перегрузка #ostream

Вопрос:

Разрешено ли напрямую возвращать во время отправки в ostream ?

Например, вместо записи:

 ostreamamp; operator<<(ostreamamp; os, Foo foo) {
    os << foo.a << foo.b;
    return os;
}
  

Вместо этого я могу напрямую написать:

 ostreamamp; operator<<(ostreamamp; os, Foo foo) {
    return os << foo.a << foo.b;
}
  

Я попробовал, и, похоже, это работает, но я не знаю, правильно ли это делать. Есть ли какие-либо проблемы с выполнением второй версии?

Комментарии:

1. Вы пробовали это с вашим компилятором?

2. Да, кажется, это работает, но я не знаю, правильно ли это делать

3. Это безопасная и довольно нормальная практика при реализации довольно простых потоковых операторов, подобных вашему примеру.

4. Это работает, потому что каждый из перегруженных операторов потока возвращает std::ostreamamp; . Итак, возвращается все выражение after return std::ostreamamp; . Оператор потока (на самом деле operator<< ) остается ассоциативным. Следовательно, os << foo.a << foo.b оценивается как ((os << foo.a) << foo.b) .

5. Почему вы думаете, что это может быть неправильно? Если вы не добавите why думаю, что это было бы неправильно, мы не можем это комментировать.

Ответ №1:

Два фрагмента кода, которые вы публикуете, полностью эквивалентны.

Почему? Потому что (я предполагаю здесь, ради аргумента, что foo.a и foo.b являются простыми типами данных, такими как int ) << оператор for std::ostream возвращает ссылку на себя (см. Раздел «Возвращаемое значение» в связанном документе).

Таким образом, в вашем первом фрагменте кода return os; строка возвращает ссылку на os объект, на который ссылается первый аргумент. В вашем втором фрагменте << каждая из двух операций оценивается как ссылка на тот же объект … таким образом, вы возвращаете ссылку на точно такой же объект.

Чтобы сделать вторую версию немного понятнее, вы можете заключить возвращаемое выражение в круглые скобки:

 ostreamamp; operator<<(ostreamamp; os, Foo foo) {
    return (os << foo.a << foo.b);
}
  

Ответ №2:

Разрешено ли напрямую возвращать, пока мы отправляем в ostream?

Да, это разрешено.