Reputation: 3430
This code would work IF I was returning by reference. My question is why can't I return by value ?
/* Boss is a struct I defined, but is literally empty */
ostream operator<<( ostream & speak, Boss y ) {
speak << "We need more profit!" << endl;
return speak;
}
int main() {
Boss b;
cout << b << endl;
}
My speculation was that maybe it is because you can't call on functions with temporary objects, but I've called on functions with temporary objects before. Is this something specific to operators ?
Upvotes: 1
Views: 57
Reputation: 320401
Because ostream
is a non-copyable object. Returning "by value" means returning a copy. Standard ostream
class does not have an accessible copy constructor, which is why it is impossible to copy ostream
objects.
This is done intentionally, specifically in order to prevent your from copying ostream
objects. There are at least two reasons why it is so.
Firstly, ostream
is essentially an abstract class, intended to serve as a base class implementing common functionality for more specific classes like ofstream
or ostringstream
. Objects of ostream
class by themselves are incomplete and unusable. Copying such objects does not make any sense - it will simply slice the object.
Secondly, when an object has exclusive ownership of some external resource, like an input-output stream, copying such object would imply duplicating that external resource as well. In many cases it is physically impossible (e.g. a program can only have one standard output stream). But even when it is possible, it is still not a good idea to make as easy as a simple copy constructor call.
In modern C++ (C++11) objects like that often support move semantics, which makes it possible to pass such objects around "by moved value" (let's call it that). But since ostream
is just a base class, in ostream
the corresponding constructor is protected, i.e. it is not accessible from outside. It becomes publicly accessible only in more specific stream classes, like ofstream
or ostringstream
.
Upvotes: 7