Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > C++ Moderated > Return type of ...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 3 Topic 9764 of 9984
Post > Topic >>

Return type of ternary ?: and Sutter's GOTW 48 revisited

by aleethorp@[EMAIL PROTECTED] Jul 3, 2008 at 03:44 PM

I was revisiting Sutter's More Exceptional C++ and got stuck on the
very first item! This used to compile (and still does with GCC 3.4.4)
but fails under GCC 4.1.3, 4.2.3 (probably all of the GCC 4.x.y) and
also fails under the VC++ 9.0 C++ compiler.

#include <fstream>
#include <iostream>

int main( int argc, char* argv[] )
{
   using namespace std;

   (argc > 2
     ? ofstream(argv[2], ios::out | ios::binary)
     : cout) // <-- line 10
   <<
   (argc > 1
     ? ifstream(argv[1], ios::in | ios::binary)
     : cin)
   .rdbuf();
}

The G++ error is :

$ g++ echo.cc
/usr/include/c++/4.1.3/bits/ios_base.h: In copy constructor
‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const
std::basic_ios<char, std::char_traits<char> >&)’:
/usr/include/c++/4.1.3/bits/ios_base.h:779: error:
‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.1.3/iosfwd:55: error: within this context
/usr/include/c++/4.1.3/iosfwd: In copy constructor
‘std::basic_ostream<char, std::char_traits<char>
>::basic_ostream(const std::basic_ostream<char, std::char_traits<char>
>&)’:
/usr/include/c++/4.1.3/iosfwd:64: note: synthesized method
‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const
std::basic_ios<char, std::char_traits<char> >&)’ first required here
echo.cc: In function ‘int main(int, char**)’:
echo.cc:10: note: synthesized method ‘std::basic_ostream<char,
std::char_traits<char> >::basic_ostream(const std::basic_ostream<char,
std::char_traits<char> >&)’ first required here

The VC++ error is similar but also picks up a second problem:

C:\>cl echo.cc
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08
for 80x86 Copyright (C) Microsoft Cor****ation.  All rights reserved.

echo.cc
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\xlocale(342) :
warning C4530: C++ exception handler used, but unwind semantics are
not enabled.
Specify /EHsc
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\ostream(584) :
error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot
access private
member declared in class 'std::basic_ios<_Elem,_Traits>'
         with
      [
             _Elem=char,
             _Traits=std::char_traits<char>
         ]
         C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE
\ios(151)
: see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
         with
      [
             _Elem=char,
             _Traits=std::char_traits<char>
         ]
         This diagnostic occurred in the compiler generated function
'std::basic_ostream<_Elem,_Traits>::basic_ostream(const
std::basic_ostream<_Elem,_Traits> &)
'
         with
      [
             _Elem=char,
             _Traits=std::char_traits<char>
         ]
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\istream(846) :
error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot
access private
member declared in class 'std::basic_ios<_Elem,_Traits>'
         with
      [
             _Elem=char,
             _Traits=std::char_traits<char>
         ]
         C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE
\ios(151)
: see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
         with
      [
             _Elem=char,
             _Traits=std::char_traits<char>
         ]
         This diagnostic occurred in the compiler generated function
'std::basic_istream<_Elem,_Traits>::basic_istream(const
std::basic_istream<_Elem,_Traits> &)
'
         with
      [
             _Elem=char,
             _Traits=std::char_traits<char>
         ]

VC++ 9 also complains about a problem with the compiler synthesized
basic_istream copy constructor (which GCC doesn't pick up until you
correct the first problem).

So here's the question: What is "?:" actually doing and why?

If the compiler error message is quite clear: its synthesizing a copy
constructor (which presumably then results in an access check - or is
it the other way around - a required copy constructor access check
that causes the copy constructor to be synthesized). But why does it
need to do this? cout is not a tem****ary.

If I fix the first GCC error:

#include <iostream>
#include <fstream>

int main(int argc, char* argv[])
{
   using namespace std;
   ofstream out;

   (argc > 2
    ? out.open(argv[2], ios::binary | ios::out), out
    : cout)
     <<
     (argc > 1
      ? in.open(argv[1], ios::binary | ios::in), in
      : cin)   // <-- line 15
       .rdbuf();
}

then the GCC compiler tries to synthesize a copy constructor due to
line 15. Here is the error:

$ g++ echo.cc
/usr/include/c++/4.1.3/bits/ios_base.h: In copy constructor
‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const
std::basic_ios<char, std::char_traits<char> >&)’:
/usr/include/c++/4.1.3/bits/ios_base.h:779: error:
‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.1.3/iosfwd:55: error: within this context
/usr/include/c++/4.1.3/iosfwd: In copy constructor
‘std::basic_istream<char, std::char_traits<char>
>::basic_istream(const std::basic_istream<char, std::char_traits<char>
>&)’:
/usr/include/c++/4.1.3/iosfwd:61: note: synthesized method
‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const
std::basic_ios<char, std::char_traits<char> >&)’ first required here
echo.cc: In function ‘int main(int, char**)’:
echo.cc:15: note: synthesized method ‘std::basic_istream<char,
std::char_traits<char> >::basic_istream(const std::basic_istream<char,
std::char_traits<char> >&)’ first required here

Again, this is wierd since clearly, cin is not a tem****ary.

Is this error artifact of the way ?: determines its resulting type
expression.
Replicating the first fix makes the problem go away.

#include <iostream>
#include <fstream>

int main(int argc, char* argv[])
{
   using namespace std;
   ofstream out;
   ifstream in;

   (argc > 2
    ? out.open(argv[2], ios::binary | ios::out), out
    : cout)
     <<
     (argc > 1
      ? in.open(argv[1], ios::binary | ios::in), in
      : cin)
       .rdbuf();
}





-- 
      [ See http://www.gotw.ca/resources/clcm.htm
for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
 




 3 Posts in Topic:
Return type of ternary ?: and Sutter's GOTW 48 revisited
aleethorp@[EMAIL PROTECTE  2008-07-03 15:44:25 
Re: Return type of ternary ?: and Sutter's GOTW 48 revisited
"Bo Persson" &l  2008-07-04 19:26:57 
Re: Return type of ternary ?: and Sutter's GOTW 48 revisited
Alberto Ganesh Barbati &l  2008-07-05 16:49:59 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sun Sep 7 8:35:44 CDT 2008.