Use Anonymous Streams

An anonymous stream is a stream that is created as a temporary object. Because it is a temporary object, an anonymous stream requires a const type modifier and is not a modifiable lvalue. Unlike the ATT C++ Language System Release 2.1, the compiler does not allow a non-const reference argument to be matched with a temporary object. User-defined input and output operators usually accept a non-const reference (such as a reference to an istream or ostream object) as an argument. Such an argument cannot be initialized by an anonymous stream, and thus an attempt to use an anonymous stream as an argument to a user-defined input or output operator will usually result in a compile-time error.

In the following example, three ways of writing a character to and reading it from a file are shown:

  1. Function f() uses anonymous streams with the built-in char type. This compiles and runs successfully.
  2. Function g() uses anonymous streams with a class that has a char as its only data member, and that has input and output operators defined for it. This produces a compilation error if you define anon when you compile. Otherwise, this part of the program is not compiled.
  3. Function h()uses named streams to write a class object to and read it from a file. This compiles and runs successfully:
// Using anonymous streams

#include <fstream.h>

class MyClass {
public:
  char a;
};

istream& operator>>(istream& aStream, MyClass mc) {
  return aStream >> mc.a;
}

ostream& operator<<(ostream& aStream, MyClass mc) {
  return aStream << mc.a;
}

// 1. Use an anonymous stream with a built-in type; this works

void f() {
  char a = 'a';

  // write to the file
  fstream(“file1.abc”,ios::out) << a << endl;

  // read from the file
  fstream(“file1.abc”,ios::in) >> a;

  // show what was in the file
  cout << a << endl;
}

#ifdef anon

// 2. Use an anonymous stream with a class type
// This produces compilation errors if “anon” is defined:

void g() {
  MyClass b;
  b.a ='b';

  // write to the file
  fstream(“file1.abc”,ios::out) << b << endl;

  // read from the file
  fstream(“file1.abc”,ios::in) >> b;

  // show what was in the file
  cout << b << endl;
}

#endif

// 3. Use a named stream with a class type; this works

void h() {
  MyClass c;
  c.a ='c';

  // define and open the file
  fstream File2(“file2.abc”,ios::out);

  // write to the file
  File2 << c << endl;

  //close the file
  File2.close();

  // reopen for input
  File2.open(“file2.abc”,ios::in);

  // read from the file
  File2 >> c;

  // show what was in the file
  cout << c << endl;
}

int main(int argc, char *argv[]) {
  f();
#ifdef anon
  g();
#endif
  h();
  return 0;
}

If you compile the above example with anon defined, compilation fails with messages that resemble the following:

Call does not match any argument list for "ostream::operator<<".
Call does not match any argument list for "istream::operator>>".

If you compile without anon defined, the letters 'a' and 'c' are written to standard output.

Related Concepts