我想改变这个工作代码:
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背景,其中对象是一直在创建的。
谢谢!
答案 0 :(得分:3)
ostream_iterator<T>
构造函数将非const
引用带到流对象,而temporaries最多可以作为const
引用传递(至少在C ++ 03);在this question中很好地解释了这一点的基本原理。
顺便说一句,这里没有太多关于如何传递流的选择:const
引用没有意义(ostream_iterator
有到修改流),并且普通ostream
是不可接受的,因为它是不可复制的(切片会杀死多态)。
在Python中,您可以随时处理构建/传递内容,因为您始终处理引用到引用计数(和垃圾收集)物体
C ++对象语义完全不同 - 对象是对象,而不是引用;要获得类似于Python的语义,您必须使用new
动态分配每个对象,并将它们包裹在shared_ptr<T>
中。
在C ++中保持所有明确命名的
更好
不一定 - 创造临时工作是完全正常的,但你必须意识到你能做什么,不能做什么,参考如何影响他们的生命等等。
答案 1 :(得分:0)
我从编译器中收到以下错误消息,解释了它。
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>]
答案 2 :(得分:0)
在C ++中,我们还经常构建对象,但需要考虑所有权问题。
ostream_iterator<int>(ofstream("my_file.txt"))
的问题是临时对象被传递给构造函数,但构造的ostream_iterator
对象并不承担临时对象的所有权。如果ostream_iterator
不是临时的,它将继续在下一行代码中保留无效引用。
通过传递身份功能或通过强制转换,可以解决这个问题。但是他们通常牺牲安全性,因为如果你在持久变量上使用这样的机制,它将创建一个悬空引用。
当你有几个通过引用链接的对象,没有容器包含的关系时,当前的C ++最佳实践是使用命名对象,而不是临时对象。
如果您不喜欢这样,您可以选择更频繁地使用共享指针。该模式允许在多个引用之间共享所有权,并隐藏容器。但这不是iostream的一部分,而且作为设计决定,这里有点可疑。