Подтвердить что ты не робот

Почему С++ iostreams всегда левая?

Я изучаю С++ и никогда не занимался потоками. Я бы предположил, что обозначение будет следующим:

std::cout << "foo";
char foo << std::cin;

Я уверен, что есть веская причина: std::cin >> foo. Что это?

4b9b3361

Ответ 1

Это связано с ассоциативностью < и → операторов.

Они были первоначально только для смещения бит, где они оставлены ассоциативными. Ассоциативность операторов остается неизменной при перегрузке (иначе код будет невозможно разобрать):

Если вы сделали

 int a, b ;
 a << b << cin

вы получите

(a << b) << cin

Сдвиг бит и ввод

Вот почему стандартная библиотека делает это так, как делает.

Ответ 2

a << b и a >> b являются просто сокращенными для:

operator<<(a,b)

и

operator>>(a,b)

(или эквивалентные функции-члены).

То есть, они просто звонки на определенные функции. Так получилось, что стандартная библиотека С++ перегружает operator<< для выполнения потоковой передачи вывода на ostream s и operator>> для выполнения потоковой передачи из istream s.

Эти функции только перегружены, чтобы иметь поток слева.

Есть две причины для этого решения. Первая - это нотационная простота (то есть, поскольку существует только один способ упорядочения операндов, существует меньше двусмысленности в отношении значения какого-либо конкретного кода, и меньше необходимости внедрять огромное количество различных перегрузок при расширении стандартной библиотеки до поддержка дополнительного класса). Во-вторых, << и >> остаются ассоциативными, и поэтому:

int a, b;
a << b << cin;

станет:

(a << b) << cin;

а

int a, b;
cin >> b >> a;

правильно становится:

(cin >> b) >> a;

Ответ 3

Это так, что вы будете вынуждены положить консоль слева так, как бог намеревался!:)

На самом деле это связано с чем-то, что называется перегрузкой оператора. Если вы просто изучаете С++, вы, вероятно, еще не рассказали об этом, но покажите, что я собираюсь сказать в разделе "Я буду позже".

С++ живет поверх C. В C << и >> используются только операторы сдвига бит. В С++ это может быть больше. std:cout << foo НЕ C, это С++. Причина этого в С++ заключается в том, что объект std::cout перегружает оператор << для обозначения чего-то другого, кроме смещения бит.

Другими словами, << означает только отправку foo в cout, потому что cout сказал, что это значит. << является, по сути, функцией класса cout.

Это почти как если бы вы сказали std::cout->sendThatToMe(foo).

Во всем этом деле foo - это просто беспроигрышный параметр для поездки, который не может сказать, что означает <<. Вот почему вы не можете сделать это по-другому. Если бы вы это сделали, это было бы так, как если бы вы говорили это:

foo->sendMeToThat( std::cout).

Что можно заставить работать, если вы добавите эту функцию (ну и действительно оператор >>) на любой вонючий объект, который вы когда-либо захотите отправить на консоль. О, и удача, тянущая его с примитивами.

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

Ответ 4

Это так, как они должны работать. Я думаю, что это было сделано, чтобы четко различать операции ввода ( → ) из выходных операций (< <).
Если вы перегружаете оператор << таким образом (как сказал капитан Очевидный в комментариях):

template<typename T>
std::istream& operator<<( T& data , std::istream& is )
{
    is >> data;
    return *this;
}

Менее понятно, был ли вход или выход оператором (с std::cin std::cout его легко, но вещь о двух потоках с именем file1 и file2, одна для чтения и одна для написания):

a << std::cin;
std::cout << a;

a << file;
file << a;