When I try to use a ternary conditional operator (?:) with stream buffer redirection, gcc produces ‘synthesized method first required here’ error. What is the problem, and how to correct the following program?
#include <fstream>
#include <iostream>
int main(int argc, char* argv[])
{
using namespace std;
cout << cin.rdbuf(); //OK
ofstream("tmp.txt") << cin.rdbuf(); //OK
int i=1;
(i > 1 ? ofstream("tmp.txt") : cout) << cin.rdbuf(); //Compilation ERROR. Why?
return 0;
}
compiled with gcc4.4:
...
/usr/include/c++/4.4/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.4/bits/ios_base.h:790: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.4/iosfwd:47: error: within this context
/usr/include/c++/4.4/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.4/iosfwd:56: 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**
../item1_1.cpp: In function ‘int main(int, char**)’:
../item1_1.cpp:12: 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
This compiled OK with my version of clang, I think that it may be a gcc bug.
From my reading of the standard,
coutis an lvalue of typestd::ostreamandofstream("tmp.txt")is an rvalue of typestd::ofstream.Neither has any cv-qualifiers and
std::ostreamis a base class ofstd::ofstreamso the conditional operator is valid an the result is an rvalue and has typestd::ostream.There is no copying of either operand implied.
The
operator<<overload that you are using is a member ofstd::ostreamso there is no need to bind a temporary to a non-const reference, the member can be called on a non-const rvalue.Edit
Note that this has changed in C++0x. Now, if the result of a conditional expression is an rvalue a temporary copy is always made. As objects of type
ostreamare not copyable your code will not be valid in C++0x.See here: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#446