First, an example to illustrate the morals behind my question: the below code will not compile, because std::basic_ostream::operator<< is not const
-qualified. (https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.4/ostream-source.html shows that the operator is not const
-qualified.)
I compiled with GNU g++ 6.4.0 compiler, with --std=c++11 flag on.
#ifndef TEST_H
#define TEST_H
#include<string>
#include<iostream>
using namespace std;
class ChessPiece{
const string name;
const int side;
public:
ChessPiece(const string&,const int);
void printPiece(const ostream&) const;
};
#endif // TEST_H
...and test.cpp.
#include"test.h"
ChessPiece::ChessPiece(const string& s,const int bw): name{s}, side{bw} {}
void ChessPiece::printPiece(const ostream& S=cout) const{
S << "a " << (side==1?"white ":"black ") << name << endl;
}
int main(){
ChessPiece p{string("pawn"),-1}; // a black pawn
p.printPiece();
}
However, I am not sure as to why these kind of errors should occur in the first place, even though operator<< is, as in the above code, logically const
.
Yes, the obvious answer would be that "operator<<
changes the inner state of std::ostream
in some way".
However, I know that by making the members mutable
we can change the contents of the class, as long as the const
-qualified function is logically const
. I also know that an instance of std::ostream
will not logically differ in any way before and after calling its operator<<
. (If anything I wrote is wrong, please point it out. Thank you)
Rephrased,
Why is the logically const
std::basic_ostream::operator<< not const
-qualified, instead of having some of its members mutable?
Thank you in advance.
You said:
I also know that an instance of
std::ostream
will not logically differ in any way before and after calling itsoperator<<
.
That's one way to look at an std::ostream
. Another way to look at it is that it is an interface to a device -- a file, a console, a string, etc. If a member function in that interface changes the underlying device, it is misleading to make that member function a const
member function.
The notion of const
is conceptual. Take a look at one my answers that explores the subject a bit. Yes, one could have made the operator<<
functions work with const std::stream
objects but it makes more sense that they are not. They are changing the underlying device that they provide an interface for and, IMO, it's better that they work with non-const
objects of type std::ostream
.