关于临时ostream对象的c++问题

c++ problems with temporary ostream objects

本文关键字:c++ 问题 对象 于临时 ostream      更新时间:2023-10-16

我想转换这个工作代码:

ofstream outfile("my_file.txt");
copy(v.begin(), v.end(), ostream_iterator<int>(outfile));

这:

copy(v.begin(), v.end(), ostream_iterator<int>(ofstream("my_file.txt")));

换句话说,我使用了ofstream对象的"匿名"或未命名版本。

两个问题:

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

(2)第二次尝试在风格上是好的,还是在c++中保持所有东西的显式命名更好?我来自Python背景,对象总是在运行中创建的。

谢谢! !

ostream_iterator<T>构造函数接受一个非const 指向流对象的引用,而临时函数最多只能作为const引用传递(至少在c++ 03中是这样);这个问题很好地解释了其基本原理。

顺便说一下,这里没有太多选择如何传递流:const引用没有意义(ostream_iterator 来修改流),普通的ostream是不可接受的,因为它是不可复制的(切片会杀死多态性)。

在Python中,你可以在运行中构造/传递东西,因为你总是处理引用计数(和垃圾收集)对象引用。c++的对象语义是完全不同的——对象是对象,而不是引用;要获得类似于Python的语义,你必须使用new动态分配每个对象,并将它们封装在shared_ptr<T>中传递。

在c++中是否所有的东西都显式命名为

更好?

不一定——创建临时是很正常的,但是你必须知道你能用它们做什么,不能做什么,引用如何影响它们的生命周期,等等。

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

std::ostream_iterator的构造函数接受一个非const引用。没有一个版本的构造函数接受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>]

在c++中,我们也经常动态地构造对象,但是需要注意所有权的问题。

ostream_iterator<int>(ofstream("my_file.txt"))的问题是临时对象被传递给构造函数,但是构造的ostream_iterator对象不承担临时对象的责任。如果ostream_iterator不是临时的,它将在下一行代码中继续保存无效引用。

有几种方法可以解决这个问题,通过传递给恒等函数或通过强制转换。但它们通常会牺牲安全性,也就是说,如果在持久变量上使用这种机制,它将创建一个悬空引用。

当你有几个对象通过引用链接时,没有容器包含的关系,当前的c++最佳实践是使用命名对象,而不是临时对象。

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