使用流缓冲区直接使用?:运算符时出现C++错误

Dav*_*sid 3 c++ iostream c++11

当我尝试使用带有流缓冲区重定向的三元条件运算符(?:)时,gcc会生成'此处首先需要的合成方法'错误.有什么问题,以及如何纠正以下程序?

#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;
}
Run Code Online (Sandbox Code Playgroud)

用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   
Run Code Online (Sandbox Code Playgroud)

CB *_*ley 5

这与我的clang版本编译好,我认为它可能是一个gcc bug.

从我的标准的阅读,cout是一个左值类型的std::ostreamofstream("tmp.txt")右值类型std::ofstream.

既不具有任何cv修饰符std::ostream是一个基类的std::ofstream这样的条件运算符是有效的结果是一个右值,且类型std::ostream.

没有隐含任何操作数的复制.

如果E1E2具有类类型,和底层类类型是相同的或一个是基类的其他的:E1可以转换为匹配E2如果类的T2是相同的类型,或基类,类的T1,并cv资格证书T2与cv资格证书相同,或者是cv资格证书T1.如果应用转换,E1则更改为T2仍然引用原始源类对象(或其相应子对象)的类型的右值.[ 注意:即没有复制.]

operator<<您正在使用的重载是成员,std::ostream因此不需要将临时绑定到非const引用,可以在非const rvalue上调用该成员.

basic_ostream<charT,traits>&
    basic_ostream<charT,traits>::operator<< (basic_streambuf<charT,traits>* sb);
Run Code Online (Sandbox Code Playgroud)

编辑

请注意,这已在C++ 0x中更改.现在,如果条件表达式的结果是rvalue,则始终会生成临时副本.由于类型的对象ostream不可复制,因此您的代码在C++ 0x中无效.

见这里:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#446