why can't I use cout with without iostream

Basically what the tittle says

I wanted to output something so I only included the ostream library

but when I tried to output something with cout i saw an error, saying that cout is undeclared and undefined.

looking around I saw this https://stackoverflow.com/questions/47416178/cout-not-working-with-ostream-header-file

but the answer didn't satisfy me.

Can someone please build up and elaborate on that answer.A few other things I would like to know are why can we include ostream if cout is of type OStream that is inside iostream? And if ostream is useless then why isn't it protetected?Does it serve a purpose besides being used in iostream?
yes, it is used by other things than iostream. This is why it is a distinct base class; to be reused by multiple higher level classes including iostream.
Some of the users include cerr and ostringstream. This lower level class does the stream work, but it does not know whether the stream is going to a file, a string, the console output, or whatever else.

you can include it because you may be trying to build your own object that inherits functionality from it. Its not really meant to be included in a typical c++ source file as a staple / common header.

I dunno how better to explain... lets see..
say you wanted to write your own simple ascii compatible string class, because whatever reasons. You decide that you want to store your characters in vectors of bytes.
Now, can you see why including <vector> does not grant you the ability to use your string class? Inheritance is a one way street (for normal, sane programmers at least). Every one of your strings has a or is a vector, but no vector has or is one of your strings -- vector is completely unaware of your class and including it won't grant access. Its exactly like that: including ostream does nothing for cin/cout usage because cin and cout are built from it, but it is unaware of that just as your strings are not known to the vectors.

Or one last way of saying it... all girls are people, but not all people are girls. Its like that... all iostreams are ostreams, but not all ostreams are iostreams.

Does that help? I kept it sort of simple because I don't know what your skill level is. If you have not spent some time with objects, OOP, and inheritance, these ideas can get confusing -- it took me a fairly long time to adjust as I was 'raised' on C like procedural programming models and styles.
Last edited on
jonnin wrote:
Its not really meant to be included in a typical c++ source file as a staple / common header.

I disagree. If you just want to overload the << operator for your type (or create another function that can output to any ostream) then there is no reason to include <iostream>, <sstream>, <fstream>, etc.

1
2
3
4
5
6
7
8
9
10
11
12
#include <ostream>

struct Point
{
	int x;
	int y;
};

std::ostream& operator<<(std::ostream& os, const Point& p)
{
	return os << "{" << p.x << ", " << p.y << "}";
}


Last edited on
Can someone please build up and elaborate on that answer.A few other things I would like to know are why can we include ostream if cout is of type OStream that is inside iostream? And if ostream is useless then why isn't it protetected?Does it serve a purpose besides being used in iostream?

The type std::ostream is defined in the header file <ostream>:
https://en.cppreference.com/w/cpp/header/ostream

Meanwhile, the global variables std::cout and std::cerr are provided by the header file <iostream>:
https://en.cppreference.com/w/cpp/header/iostream


Even though the global variables std::cout and std::cerr are of the type std::ostream, it is perfectly possible to use the type std::ostream without using the global variables std::cout and std::cerr – and, in that case, you'd just include the <ostream> header. But, if you want to use the global variables std::cout and std::cerr, then including <iostream> is what you want 😏

In other words, the type std::ostream, which is defined in the <ostream> header, is not "useless" without the <iostream> header, because that type can very well be used for purposes that are not related to std::cout or std::cerr at all! Only if you actually want to use std::cout or std::cerr, then you'll have to include the <iostream> header, because that's where those global variables are declared.

So, yeah, std::ostream is somewhat realted to std::cout (and std::cerr), but they obviously are not the same thing. The former may be used alone without using the latter at all... And that is probably the reason why they are declared in separate header files!

(Note that <iostream> implicitly includes <ostream>, but this does not apply the other way around!)

______________________________


Consider the following example program:

main.cpp
1
2
3
4
5
6
7
8
#include <iostream>
#include <string>

void write_string(std::ostream &dst, const std::string &src);

int main() {
	write_string(std::cout, "Hello World!");
}

utils.cpp
1
2
3
4
5
6
#include <ostream>
#include <string>

void write_string(std::ostream &dst, const std::string &src) {
	dst << '"' << src << "\"\n";
}


Note how "utils.cpp" does not know anything about std::cout or std::cerr, but rather accepts a reference to an arbitrary std::ostream instance to which it is going to write, and therefore it does not need to include the <iostream> header 😏
Last edited on
Peter87 wrote:
I disagree. If you just want to overload the << operator for your type (or create another function that can output to any ostream) then there is no reason to include <iostream>, <sstream>, <fstream>, etc.


This is fair ... I rarely need << operator, so almost never include it, but it could easily be something you do a lot.
Registered users can post here. Sign in or register to post.