简体   繁体   中英

Why can I use `operator<<` on temporary std::ofstream objects?

According to the C++ standard you cannot bind a temporary to a non-const reference. Since the stream output operator is defined as

template <class CharT, class Traits, class Allocator>

std::basic_ostream<CharT, Traits>&
    operator<<(std::basic_ostream<CharT, Traits>& os,
               const std::basic_string<CharT, Traits, Allocator>& str);

I would expect it to not be callable on temporary stream objects. However, I tried the following and got unexpected results

#include <fstream>

std::ostream& print(std::ostream &stream) {
    stream << "test\n";
    return stream;
}

int main() {
    std::fstream("") << "test\n";
    // print(std::fstream("")); // Doesn't compile, as expected
}

This compiles on GCC trunk, Clang trunk and MSVC 19. I even tried -pedantic-errors on the first two. While technically possible that all three are wrong, it is likely that I am misunderstanding something.

Can somebody find a definitive answer in the standard on whether this is legal C++ or not?

There is overload which takes stream by Rvalue reference:

template< class CharT, class Traits, class T >
basic_ostream< CharT, Traits >& operator<<( basic_ostream<CharT,Traits>&& os,
                                        const T& value );

temp is passed as os . From reference .

The C++ standard mandates the following function template existing (C++17 n4659 30.7.5.5 [ostream.rvalue]):

template <class charT, class traits, class T>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&& os, const T& x);

With effects specified as os << x .

Note that the same exists for extraction ( >> ) as well.

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