Thread overview
why difference between temp and named variable?
Apr 22, 2004
Steve Strand
Apr 23, 2004
Heinz Saathoff
Apr 23, 2004
Steve Strand
April 22, 2004
This program fails as written, but a fix
is shown in comments:

#include <iostream.h>
#include <strstream.h>

struct mine
{
    int a;
};

ostream& operator << (ostream& out, mine& m)
{
    return out << m.a;
}

istream& operator >> (istream& in, mine& m)
{
    return in >> m.a;
}

int main()
{
    mine mm;

//these two lines work
//  istrstream in("106");
//  if (in >> mm)

//but this one line alternative does not work
    if (istrstream("106") >> mm)

        cout << "mm= " << mm << endl;
    else
        cout << "extract fails" << endl;
}


The bad version gets this error message:
    cannot generate copy constructor for class
    'istream' because of private 'ios'

Why does the compiler need to generate a copy
constructor? The code creates a temporary istrstream,
passes it by reference to operator>>(), then uses the
returned reference to call member function ios::operator
void*(). Neither passing by reference nor calling a
member function involves copy constructing.

Why does the commented-out version work? Giving the istrstream a name instead of using a temp should not influence the need for a copy constructor.


April 23, 2004
Hello Steve,

Steve Strand wrote...
> #include <iostream.h>
> #include <strstream.h>
> 
> struct mine
> {
>     int a;
> };
> 
> ostream& operator << (ostream& out, mine& m)
> {
>     return out << m.a;
> }
> 
> istream& operator >> (istream& in, mine& m)
> {
>     return in >> m.a;
> }
> 
> int main()
> {
>     mine mm;
> 
> //these two lines work
> //  istrstream in("106");
> //  if (in >> mm)
> 
> //but this one line alternative does not work
>     if (istrstream("106") >> mm)

You create a temporary istrstream obj here. Temporarys can only be passed to const references.

> 
>         cout << "mm= " << mm << endl;
>     else
>         cout << "extract fails" << endl;
> }

> The bad version gets this error message:
>     cannot generate copy constructor for class
>     'istream' because of private 'ios'

I think the error message is misleading here. I tried your program with PC-Lint and got this error message:

--- Module:   stru.cpp

    if (istrstream("106") >> mm)
stru.cpp  28  Info 1776: Converting a string literal
to char * is not const safe (arg. no. 1)
stru.cpp  28  Error 1058: Initializing a non-const reference
'istream &' with a non-lvalue


PC-Lint tells you that you can't pass a temporary to a non const reference which you do in your operator >> for type mine.

If you add const to your first (working) line than you will also get a error (also misleading error message but due to const). In that case my PC-Lint tells me

--- Module:   stru.cpp
                           _
  const istrstream in("106");
stru.cpp  24  Info 1776: Converting a string literal
to char * is not const safe (arg. no. 1)
              _
  if (in >> mm)
stru.cpp  25  Warning 1561: Reference initialization causes loss of
    const/volatile integrity (arg. no. 1)

I don't yet know why this is only flagged as a warning and not a error which it should be in my opinion.

- Heinz
April 23, 2004
Thank you Heinz! Your answer is helpful and insightful.

Steve