c++ - 为什么 C++23 string::resize_and_overwrite 将操作作为右值调用?
问题描述
为了提高写入数据的性能std::string
,C++23专门resize_and_overwrite()
为std::string
. 在[string.capacity]中,标准对其进行了如下描述:
template<class Operation> constexpr void resize_and_overwrite(size_type n, Operation op);
让
—
o = size()
在调用resize_and_overwrite
.——
k
成为min(o, n)
。—
p
是 acharT*
,使得范围 [p
,p + n
] 是有效的并且this->compare(0, k, p, k) == 0
在true
调用之前。p + k
[ , ]范围内的值p + n
可能是不确定的[basic.indet]。—
OP
是表达式std::move(op)(p, n)
。—
r = OP
.[...]
- 效果:计算,用 [ , )
OP
替换 的内容,并使对范围 [ , ]的所有指针和引用无效。*this
p
p + r
p
p + n
但是我发现这个函数在调用它之前会std::move
用来转换op
成一个右值,这意味着我们不能传入一个只有左值重载的可调用对象operator()
(demo):
#include <string>
int main() {
struct Op {
int operator()(char*, int) &;
int operator()(char*, int) && = delete;
} op;
std::string s;
s.resize_and_overwrite(42, op); // ill-formed
}
这种行为似乎有点奇怪,但由于这种变化是在上一版论文中做出的,显然是故意的。
那么,这背后的考虑是什么?授权中是否有任何op
必须作为右值调用的好处?
解决方案
op
在销毁之前只调用一次,因此将其作为右值调用允许对其进行任何&&
重载以重用它可能拥有的任何资源。
可调用对象在道德上是一个 xvalue - 它正在“过期”,因为它在调用后立即被销毁。如果您专门设计了您的可调用对象以仅支持作为左值调用,那么库很乐意通过阻止其工作来承担责任。
推荐阅读
- ios - 如何在 2 个 ViewControllers Objective-C 上添加 UIView
- firebase - 如何确保一次只有一个 http Cloud Function 调用的并发性
- python - Visual Studio Code Python 超时等待调试器连接
- python - 为什么我的最终图像在 putpixel 之后变成了红色?
- ios - CodeRunner:错误:缺少方法声明的上下文
- c# - 我的游戏在统一编辑器中看起来不错,但在 Android 中它不起作用
- python - 运行我的第一个 kivy 代码以显示空白屏幕后弹出错误
- c - 输出有时会失败
- c - 打印链接列表中head指向的项目时的取消引用错误
- karate - karate netty server - 如何发送 PDF/ZIP 文件作为 netty 服务器响应?