Необходимость объявить «глобальную перегрузку оператора друга» для выполнения сериализации всегда казалась мне глупой.Не казалось основополагающим объявление операторов сериализации за пределами вашего класса.Поэтому я искал убедительный ответ, почему.
(Примечание: если у кого-то есть более хороший Google-Fu, чтобы найти хороший ответ, уже написанный, мне было бы интересно прочитать это.)
Что я подозреваю, так это то, что это технически возможно, и это только нотационная проблема.Если бы библиотека была разработана для перегрузок элементов <<
и >>
, вам пришлось бы строить строку потоковых операций справа налево, а не слева направо.Поэтому вместо того, чтобы писать:
Rational r (1, 2);
cout << "Your rational number is " << r;
Вы должны записать строку вывода в виде:
r >> ("Your rational number is " >> cout);
Скобки необходимы, чтобы начать обратное связывание, потому что >>
и <<
ассоциируется слева направо.Без них он попытается найти совпадение для r >> "Your rational number is "
до "Your rational number is " >> cout
.Если бы был выбран оператор с ассоциативностью справа налево , этого можно было бы избежать:
r >>= "Your rational number is " >>= cout;
(Примечание. Внутри библиотеки не относящиеся к классам типы, такие как строкас литералом нужно было бы позаботиться о глобальных перегрузках операторов.)
Но является ли это пределом, и это обращение в значительной степени неизбежно для любого дизайна в стиле iostream, который хотел, чтобы сериализация отправлялась в класс?Я пропускаю какие-либо другие проблемы?
ОБНОВЛЕНИЕ Возможно, лучше сформулировать "проблему", чтобы сказать, что я подозревал следующее:
Для непотоковых объектов, которые хотят сериализовать себя, библиотека iostream МОЖЕТ гипотетически спроектирована так, чтобы вставки и экстракторы были членами класса вместо глобальных перегрузок ... и без (значительного) влияния на свойства среды выполнения.Тем не менее, это работало бы ТОЛЬКО, если бы авторы iostream согласились с этим, что заставило бы клиентов формировать потоковые операции справа налево.
Но мне не хватает интуиции о том, почему глобальная перегрузка оператора противучастник может разблокировать иначе разблокируемую способность выражать себя слева направо (вместо справа налево).Вопрос в том, могут ли альтернативные варианты задним числом или шаблоны, или какая-то эзотерическая особенность C ++ 11.ИЛИ имеет ли «физика С ++» присущий одно направление другому, и глобальная перегрузка является каким-то единственным приемом компиляции во время компиляции в книге для ее переопределения.
Сравните с Правило левой руки Флемингадвигатели