c++ - why difference between temp and named variable?
- Steve Strand (40/40) Apr 22 2004 This program fails as written, but a fix
- Heinz Saathoff (29/65) Apr 23 2004 You create a temporary istrstream obj here. Temporarys can only be
- Steve Strand (2/2) Apr 23 2004 Thank you Heinz! Your answer is helpful and insightful.
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.
Apr 22 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
Apr 23 2004
Thank you Heinz! Your answer is helpful and insightful. Steve
Apr 23 2004