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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With