Myslim ze michas dohromady 2 veci ktery spolu uplne nesouvisi.
Jedna vec je abstrakce datovych proudu, to znamena nejake jednotne rohrani pro cteni/zapis na ruzna mista - standardni vystup, soubor, socket, ...
Druha vec je pretizeni operatoru pro bitovy posun (<<, >>).
Podle me hlavni duvod pro pouziti tehle operatoru je ten, ze stare verze c++ neumoznovali vytvorit typovane variadicke funkce. Troufnu si tvrdit ze kdyby c++ streamy vznikali dnes, tak misto:
std::cout << a << b << c;
by se psalo:
std::cout.print(a, b, c);
pripadne neco jako:
std::cout.printf("a = %, b = %, c = %", a, b, c);
V novych verzich c++ by nebyl problem vytvorit takovehle rozhrani s tim ze by se u vseho kontrolovali typy. V dobe kdy vznikly streamy to mozne nebylo.
Mimochodem, printf() ma zasadni problemy, kvuli kterym je lepsi tuhle funkci nepouzivat:
- ve formatovacim retezci musis zadat spravny typ, jinak program muze snadno spadnout. Pravda, nektere kompilatory zobrazi warning.
- musis ZNAT spravny typ - to muze byt problem napr. u sablon, ale ne jenom tam. Nekere typy se muzou lisit system od systemu. Vytiskne se spravne napr. promenna typu size_t, kdyz pouziju "%d"?
- neni rozsiritelna. Operator << muzu snadno pretizit a tisknout instance vlastni tridy stejne jako vsechno ostatni. S printf() tohle udelat nemuzu.