C ++ issues with ostream temporary objects

I thought to convert this working code:

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

in it:

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

In other words, I am using an “anonymous” or unnamed version of thestream object.

Two questions:

(1) Why is the second attempt not working?

(2) Is the second attempt even a good style or is it better in C ++ to keep everything explicitly named? I come from the Python background, where objects are created on the fly all the time.

Thanks!!

+4
source share
3 answers

The ostream_iterator<T> constructor takes a const reference to a stream object, while temporary files can be transferred no more than const links (at least in C ++ 03); The rationale for this is well explained in this question .

By the way, there wasn’t much choice on how to pass the stream: the const link didn’t make sense ( ostream_iterator should change the stream), and a simple ostream unacceptable because it is not copied (the slice kills polymorphism).

In Python, you can get away with constructing / passing stuff on the fly, because you always deal with object references with reference counting (and garbage).

The semantics of a C ++ object are radically different - an object is an object, not a link; to get semantics like Python, you will need to dynamically highlight each object with new and pass them around, enclosed in shared_ptr<T> .

better in C ++ to keep everything explicitly named

Not necessarily - it’s completely normal to create temporary sections, but you should know what you can and cannot do with them, how links affect their lives, etc.

+3
source

I get the following error message from my compiler that explains this.

Constructor

std::ostream_iterator accepts a non-const link. There is no constructor version that accepts 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>] 
0
source

In C ++, we also often build objects on the fly, but we need to consider ownership issues.

The problem with ostream_iterator<int>(ofstream("my_file.txt")) is that the temporary object is passed to the constructor, but the constructed ostream_iterator object does not take responsibility for temporary responsibilities. If ostream_iterator also not temporary, it continued to hold the invalid link in the next line of code.

There are ways to get around this by going to the identification function or by casting. But they tend to sacrifice security, in the sense that if you use such a mechanism for a constant variable, it will create a dangling link.

If you have multiple objects linked by links without binding to a container, the current best practice of C ++ is to use named objects, not temporary ones.

If you don't like this, you can use generic pointers more often. This template allows you to share property between multiple links, while the container is hidden. But this is not part of iostreams, and as a constructive solution here would be a little doubtful.

0
source

All Articles