为什么在临时std :: ofstream对象上使用`operator <<`?

pat*_*gan 6 c++ pass-by-reference temporary-objects

根据C ++标准,您不能将临时绑定到非常量引用。由于流输出运算符定义为

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);
Run Code Online (Sandbox Code Playgroud)

我希望它不能在临时流对象上调用。但是,我尝试了以下操作并获得了意外的结果

#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
}
Run Code Online (Sandbox Code Playgroud)

这可以在GCC干线,Clang干线和MSVC 19上进行编译。我什至尝试-pedantic-errors了前两个。尽管从技术上讲这三个都是错误的,但我可能误会了一些东西。

有人可以在标准中找到关于这是否合法的C ++的明确答案吗?

raf*_*x07 7

有过载,该过载通过Rvalue引用获取流:

template< class CharT, class Traits, class T >
basic_ostream< CharT, Traits >& operator<<( basic_ostream<CharT,Traits>&& os,
                                        const T& value );
Run Code Online (Sandbox Code Playgroud)

temp作为传递os。从参考


Rei*_*ica 6

C ++标准规定了以下现有功能模板(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);
Run Code Online (Sandbox Code Playgroud)

效果指定为os << x

请注意,提取(>>)同样存在。