Kacy
Kacy

Reputation: 3430

Why can't I call on the operator when I return by value instead of by reference?

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

Answers (1)

AnT stands with Russia
AnT stands with Russia

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

Related Questions