C++ c++;临时ostream对象的问题

C++ c++;临时ostream对象的问题,c++,temporary-objects,anonymous-objects,C++,Temporary Objects,Anonymous Objects,我想转换这个工作代码: ofstream outfile("my_file.txt"); copy(v.begin(), v.end(), ostream_iterator<int>(outfile)); 流出流文件的(“my_file.txt”); 复制(v.begin()、v.end()、ostream_迭代器(outfile)); 为此: copy(v.begin(), v.end(), ostream_iterator<int>(ofstream("my_fi

我想转换这个工作代码:

ofstream outfile("my_file.txt");
copy(v.begin(), v.end(), ostream_iterator<int>(outfile));
流出流文件的
(“my_file.txt”);
复制(v.begin()、v.end()、ostream_迭代器(outfile));
为此:

copy(v.begin(), v.end(), ostream_iterator<int>(ofstream("my_file.txt")));
copy(v.begin()、v.end()、ostream_迭代器(of Stream(“my_file.txt”));
换句话说,我使用ofstream对象的“匿名”或未命名版本

两个问题:

(1) 为什么第二次尝试失败了

(2)是第二次尝试,即使是很好的风格,还是C++中更好地保持所有的东西都被明确命名?我来自Python的背景,在那里,对象总是动态创建的


谢谢

ostream_迭代器构造函数对流对象进行非
常量
引用,而临时变量最多可以作为
常量
引用传递(至少在C++03中);这一点的基本原理在中有很好的解释

顺便说一句,关于如何传递流,这里没有太多选择:一个
const
引用没有意义(
ostream\u迭代器必须修改流),一个普通的
ostream
是不可接受的,因为它是不可复制的(切片会杀死多态性)

在Python中,您可以不必动态构造/传递内容,因为您总是处理对引用计数(和垃圾收集)对象的引用

<> > C++对象语义是根本不同的——对象是对象,不是引用;要获得类似Python的语义,您必须使用
new
动态分配每个对象,并将它们包装在
shared\u ptr
中传递

<> >在C++中保持所有显式命名为

更好吗?
不一定-创建临时表是完全正常的,但您必须知道可以和不能对它们做什么,引用如何影响它们的生存期,等等。

我从编译器中得到以下错误消息,解释了它

std::ostream\u迭代器的构造函数采用非常量引用。没有一个版本的构造函数采用std::ofstream

Untitled 33.cpp:21: error: no matching function for call to ‘std::ostream_iterator<int, char, std::char_traits<char> >::ostream_iterator(std::ofstream)’
/usr/include/c++/4.2.1/bits/stream_iterator.h:185: note: candidates are: std::ostream_iterator<_Tp, _CharT, _Traits>::ostream_iterator(const std::ostream_iterator<_Tp, _CharT, _Traits>&) [with _Tp = int, _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.2.1/bits/stream_iterator.h:181: note:                 std::ostream_iterator<_Tp, _CharT, _Traits>::ostream_iterator(std::basic_ostream<_CharT, _Traits>&, const _CharT*) [with _Tp = int, _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.2.1/bits/stream_iterator.h:169: note:                 std::ostream_iterator<_Tp, _CharT, _Traits>::ostream_iterator(std::basic_ostream<_CharT, _Traits>&) [with _Tp = int, _CharT = char, _Traits = std::char_traits<char>]
Untitled 33.cpp:21:错误:调用“std::ostream_迭代器::ostream_迭代器(std::ofstream)”时没有匹配函数
/usr/include/c++/4.2.1/bits/stream_iterator.h:185:注:候选项为:std::ostream_iterator::ostream_iterator(const std::ostream_iterator&)[带"Tp=int,"CharT=CharT,"Traits=std::char"Traits]
/usr/include/c++/4.2.1/bits/stream_iterator.h:181:注:std::ostream_iterator::ostream_iterator(std::basic_ostream&,const_CharT*)[带Tp=int,CharT=char,Traits=std::char_Traits]
/usr/include/c++/4.2.1/bits/stream_iterator.h:169:注:std::ostream_iterator::ostream_iterator(std::basic_ostream&)[带"Tp=int,"CharT=char,"Traits=std::char"Traits]

在C++中,我们也经常在飞行中构造对象,但是所有权的问题需要考虑。
ostream_迭代器(ofstream(“my_file.txt”)
的问题是,一个临时对象正在传递给构造函数,但构造的
ostream_迭代器
对象不承担临时对象的责任。如果
ostream\u迭代器
不是临时的,它将继续在下一行代码中保存无效引用

有很多方法可以解决这个问题,通过传递到标识函数或通过强制转换。但它们通常会牺牲安全性,因为如果对持久变量使用这种机制,它将创建一个悬空引用

当您有几个对象引用时,没有容器包含的关系时,当前C++的最佳实践是使用命名对象,而不是临时变量。


如果您不喜欢这样,可以选择更频繁地使用共享指针。该模式允许在多个引用之间共享所有权,同时隐藏容器。但这不是iostreams的一部分,作为设计决策,这里有点可疑。

因为迭代器的构造函数需要一个非常量引用,而您正在传递一个temp对象,它最多只能发送到常量引用参数。回答你的第二个问题,没有编译/工作的代码几乎不符合“良好风格”的说法。第二个版本怎么会失败?它编译吗?如果没有,错误是什么?如果是这样的话,你会得到一个运行时错误吗?+1,以防我的支持在评论中不明显。这在C++03中是正确的。在C++11中,可以将临时值作为非常量右值引用传递。@本沃伊特:我知道,但我还没有完全理解右值引用,我更不愿意谈论我不太熟悉的东西。是的,但有一种方法通过引用使用
basic\u ostream
,而流迭代器
派生自
basic\u ostream
,应该进行转换。它不会转换,因为右值无法绑定到非常量左值引用。