呼叫运营商<<临时
call operator<< on temporary
考虑以下代码(godbolt(:
#include <fstream>
#include <string>
#include <filesystem>
namespace fs = std::filesystem;
using namespace std::string_literals;
template<class CharT, class Traits>
void test(std::basic_ostream<CharT, Traits> &s) {
s << "Other testn"s;
}
struct my_struct {
std::string s = "My Structn"s;
};
template<class CharT, class Traits>
std::basic_ostream<CharT, Traits> &operator<<(std::basic_ostream<CharT, Traits> &stream,
const my_struct &s) {
stream << s.s;
return stream;
}
int main() {
fs::path file("test.txt");
const my_struct s;
// A
operator<<(std::ofstream(file, std::ios_base::app), "Other test!n"s); // Runs fine
std::ofstream(file, std::ios_base::app) << "Das ist ein Test!n"s; // Runs fine
// B
operator<<(std::ofstream(file, std::ios_base::app), s); // Runs fine
std::ofstream(file, std::ios_base::app) << s; // Runs fine
// C
// test(std::ofstream(file, std::ios_base::app)); // Does not compile
}
代码部分A和B编译得很好,而C则不然。很明显,test
不能取右值,因为参数是非const
引用。
但是A
和B
不应该是一样的吗?STL的operator<<
和我自己的都把左手边作为非const
的参考。那么,为什么他们可以使用临时对象呢?
编译器:
clang version 10.0.0
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
编辑:这个问题的第一个版本有一个错误,导致了自己的operator<<
segfault。
那么,为什么它们可以使用临时对象呢?
因为,与operator <<
不同,标准库中的一些函数不是免费的,但成员函数可以很容易地处理临时对象而没有任何问题,而非成员函数有一个显式重载,采用右值(或更精确的正向(引用。
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- 什么是临时错位
- 重载方法的方式会在使用临时调用时生成编译器错误
- 在不复制临时对象的情况下延长其生存期
- 我可以将shared_ptr作为临时传递给线程吗?
- 为什么当我们有常量引用时创建临时对象?
- 程序如何'remember'临时对象?
- C++ 协程在co_await表达式中临时
- 如何将临时 C 数组传递到 constexpr 容器中
- 返回对临时对象的引用
- 如何将临时数组传递给标准 C++17 中的函数
- 防止临时对象文件访问 MSVC 中的磁盘
- 是否可以在C++中移动临时对象的属性?
- 通过引用传递临时对象
- C++17 和静态临时生存期的参考扩展
- 临时C++对象是否为左值?
- C++通过绑定到引用成员而缩短临时变量寿命?