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! ]


|