当我尝试使用带有流缓冲区重定向的三元条件运算符(?:)时,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;
}
使用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
答案 0 :(得分:5)
这与我的clang版本编译好,我认为它可能是一个gcc bug。
根据我对该标准的解读,cout
是std::ostream
类型的左值,ofstream("tmp.txt")
是类型的右值 std::ofstream
。
cv-qualifiers 和std::ostream
都没有std::ofstream
的基类,所以条件运算符有效,结果是 rvalue 并且类型为std::ostream
。
没有隐含任何操作数的复制。
如果
E1
和E2
具有类类型,并且基础类类型相同或者一个是另一个的基类:E1
可以转换为匹配{{1如果E2
的类与T2
的类相同,或者是T1
的类的基类,则T2
的cv-qualification与cv-qualification相同,或者比T1
的cv资格更高的cv资格。如果应用了转换,则E1
将更改为仍然引用原始源类对象(或其相应子对象)的类型T2
的右值。 [注意:即没有复制。 ]
您正在使用的operator<<
重载是std::ostream
的成员,因此不需要将临时绑定到非const引用,可以在非const <上调用该成员< EM>右值
basic_ostream<charT,traits>&
basic_ostream<charT,traits>::operator<< (basic_streambuf<charT,traits>* sb);
修改强>
请注意,这已在C ++ 0x中发生了变化。现在,如果条件表达式的结果是 rvalue ,则始终会生成临时副本。由于ostream
类型的对象不可复制,因此您的代码在C ++ 0x中无效。
见这里:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#446
答案 1 :(得分:1)
您可以这样使用条件运算符:
#include <fstream>
#include <iostream>
int main(int argc, char* argv[])
{
using namespace std;
ofstream file("tmp.txt");
int i=1;
(i > 1 ? file : cout) << cin.rdbuf();
return 0;
}
这在gcc 4.4.3上为我编译。
我知道,不是你要找的单行班车。
注意:正如Evan在评论中指出的那样,这将导致即使不需要也会创建文件。
答案 2 :(得分:0)
我可以在这里看到两种可能性: