rbuf的生命周期和使用
The lifetime and the use of rdbuf
下面的代码工作,它不像它提供一些坏的或不想要的行为,如未定义的行为或不正确的结果。代码按预期工作,我的问题是:为什么?
std::vector<char> v{std::istreambuf_iterator<char>{
std::ifstream{"yourFile.txt", std::ios::in}.rdbuf()},
std::istreambuf_iterator<char>{}};
这是对std::vector
的构造函数的调用,它与迭代器一起工作,我的观点是关于rdbuf()
调用的生命周期,并且rdbuf
是一个指针而不是对象的事实,你不能只是复制rdbuf
并假装它总是会到达你的文件的内容,也不能真正复制文件的整个内容而不使用迭代器。
我期待的是:
- 有一个临时的
ifstream
对象 - 从这个临时调用
rdbuf
-
rdbuf
现在在istreambuf_iterator
的构造函数中,ifstream
对象消失了 -
std::vector
的构造函数现在应该使用指向一个不再存在的对象的指针的副本
我很惊讶这个东西能起作用,有人能说明为什么我错了,一步一步发生了什么?ifstream
对象不应该是RAII兼容的,并且只出现在istreambuf_iterator
的范围内
临时对象(当没有通过绑定到引用而延长生命期时)在封闭的完整表达式(c++ 11 12.2/3)的末尾被销毁:
每1.9/10:当实现引入具有非平凡构造函数(12.1,12.8)的类的临时对象时,它应确保为该临时对象调用构造函数。类似地,对于带有非平凡析构函数的临时函数,也应该调用析构函数(12.4)。临时对象在(词法上)包含创建它们的点的完整表达式(1.9)求值的最后一步被销毁。即使该求值以抛出异常结束也是如此。销毁临时对象的值计算和副作用只与完整表达式相关联,而不与任何特定的子表达式相关联。
full-expression不是另一个表达式的子表达式。[注意:在某些上下文中,例如未求值的操作数,语法子表达式被认为是完整表达式(第5条)。- 结束注意] 如果定义了一种语言结构来产生对函数的隐式调用,则该语言结构的使用在本定义中被认为是表达式。对非临时对象的对象生命周期结束时生成的析构函数的调用是隐式的完整表达式。为满足出现该表达式的语言结构的要求而应用于表达式结果的转换也被认为是完整表达式的一部分。
你对v
的声明"产生一个函数的隐式调用":双迭代器向量构造函数。因此,它被认为是一个完整表达式,因此临时ifstream
对象(更不用说两个临时std::istreambuf_iterator<char>
对象)在构造函数调用完成之前不会被销毁。
- 如何在共享库的整个生命周期内存储数据
- 如何理解句子的生命周期始于对e的评估
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了
- Go/C++gRPC客户端通道和存根生命周期
- 如何将"this"的生命周期移动到C++中的另一个对象中?
- 是否可以通过使用移动/交换 c++11 来延长返回的临时变量的生命周期
- 使用对象的生命周期作为设置器的安全性
- 临时人员的生命周期传递给函数
- 我想知道在构造函数中初始化变量时的生命周期
- Lua 用户数据生命周期管理
- 如何使用 epoll(void* event.data.ptr) 管理 Connection 的生命周期
- C++引用的生命周期
- 在堆栈上有一个对象,而不是在函数的整个生命周期内
- 在 Boost ASIO 服务器中处理生命周期
- C++ lambda 生命周期
- 使用互斥锁跟踪另一个应用的生命周期
- QSharedPointer 或 std::shared_ptr 的生命周期
- 来自async_resolve的 boost::asio::ip::tcp::resolver::iterator 的生命周期是多久?
- 如何调整属于类的唯一指针的字符数组的大小.它必须在程序的整个生命周期中保持活力
- 延长 std::tuple<int&,int> 的生命周期,方法是将其分配给 const std::tuple<int, int>&