4

I want to use std::ostream like this:

int main()
{
    std::ostream os;
    os << "something ..." << std::endl;
    return 0;
}

There's an error said that the ostream constructor is protected:

error: ‘std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char; _Traits = std::char_traits]’ is protected.

But I remember operator<< could be overloaded like this:

// In a class. 
friend std::ostream & operator<<(std::ostream& out, const String & s) {
    out << s.m_s;
    return out;
}

Any advice on why my code doesn't work?

Akira
  • 4,385
  • 3
  • 24
  • 46
Jaden
  • 65
  • 1
  • 1
  • 6
  • 1
    Do you have an `#include ` preprocessor directive? I also don't think there's a parameterless `ostream` constructor - see [here](http://en.cppreference.com/w/cpp/io/basic_ostream/basic_ostream). `ostream`s should be wrapped around a stream buffer - did you mean to use an `fstream` or similar instead? – hnefatl Jul 18 '17 at 16:09
  • Yes, I have included . I want to use std::ostream like the case in overloaded operator<<(). Therefore the constructor should have a streambuffer as its parameters ? – Jaden Jul 18 '17 at 16:53
  • No, I meant `#include `. Pre C++11, just including `iostream` wasn't always enough to include `ostream` (although I can't find the SO post that explains this now). Yes - you can only create an `ostream` object if you pass in a `streambuf` object as a parameter. Then the `ostream` will output to that buffer. See [this post](http://www.cplusplus.com/forum/beginner/120947/) for a simple explanation. – hnefatl Jul 18 '17 at 18:47
  • What are you actually trying to do? Update your question with your end goal. It's unlikely that you actually want to use a raw `ostream` object, it's far more likely that you want a `stringstream` or `fstream`. – hnefatl Jul 18 '17 at 18:49
  • @Jaden, I've renewed my answer. I hope that it may helps. – Akira Aug 02 '17 at 08:38

1 Answers1

6

The std::ostream, the std::istream or the std::iostream are base classes of stream types (e.g. std::stringstream, std::fstream, etc.) in the Standard Library. These classes are protected against instantiation, you can instantiate their derived classes only. The error message

error: 'std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char; _Traits = std::char_traits]' is protected

tells you the same.

Your second example is valid because you can use references to the base class of derived classes. In this case no constructor is called, a reference only refers to an existing object. Here is an example how can use std::ostream& to the std::cout:

#include <iostream>

int main() {
    std::ostream& os = std::cout;
    os << "something ..." << std::endl;
}

The reason behind using std::ostream& in overload of operator<< is that you may don't want to overload the the mentioned operator for all individual stream types, but only for the common base class of them which has the << functionality.

Akira
  • 4,385
  • 3
  • 24
  • 46
  • `std::out` is not class derived from `std::ostream`. ***It's an instance of `std::ostream`.*** ` extern ostream cout; /// Linked to standard output` is seen at `/usr/include/c++/7/iostream`. For details, see [this post](https://stackoverflow.com/questions/72687366/whats-the-relation-between-stdcout-and-stdostream/72687508#72687508). How do you think about it? – John Jun 21 '22 at 02:23
  • @John, thank you for your comment. Although I didn't state that `std::cout` is a derived class of `std::ostream`, reading my answer back so much later, I think I know what makes it a bit misleading. I used `std::cout` to give a brief and simple example of using `std::ostream&`, but feel free to modify it. – Akira Jun 21 '22 at 16:00