简体   繁体   中英

c++ problems with temporary ostream objects

I thought to transform this working code:

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

into this:

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

In other words, I use an "anonymous", or unnamed, version of the ofstream object.

Two questions:

(1) Why does the second attempt fail?

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

Thanks!!

The ostream_iterator<T> constructor takes a non- const reference to a stream object, while temporaries can be passed at most as const references (at least in C++03); the rationale for this is well explained in this question .

By the way, here there wasn't much choice about how to pass the stream: a const reference wouldn't have made sense (the ostream_iterator has to modify the stream), and a plain ostream isn't acceptable because it is non-copyable (slicing would kill polymorphism).

In Python you can get away with constructing/passing stuff on the fly because you are always dealing with references to reference-counted (and garbage-collected) objects .

The C++ object semantic is radically different - an object is an object, not a reference; to obtain a semantic similar to Python's you would have to allocate every object dynamically with new and pass them around wrapped in shared_ptr<T> .

is it better in C++ to keep everything explicitly named

Not necessarily - it's perfectly normal to create temporaries, but you must be aware of what you can and cannot do with them, how references affect their lifetime, etc.

I get the following error message from my compiler which explains it.

std::ostream_iterator 's constructor takes a non const reference. There isn't a version of the constructor that takes a 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>]

In C++ we also often construct objects on-the-fly, but issues of ownership need to be minded.

The problem with ostream_iterator<int>(ofstream("my_file.txt")) is that a temporary object is getting passed to a constructor, but the constructed ostream_iterator object doesn't take ownership of the temporary's responsibilities. If the ostream_iterator weren't also a temporary, it would continue to hold an invalid reference at the next line of code.

There are ways around this, by passing to an identity function or by casting. But they generally sacrifice safety, in the sense that if you use such a mechanism on a persistent variable it will create a dangling reference.

When you have several objects linked by references, without a container-contained relationship, current C++ best practice is to use named objects, not temporaries.

If you don't like this, you can choose to use shared pointers more often. That pattern allows the ownership to be shared between several references, with a container being hidden away. But that's not part of iostreams, and as design decision it would be a bit questionable here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM