c++ - 了解这种行为(r 值参考)
问题描述
我正在使用以下代码进行一些测试:
#include <iostream>
#include <string>
using namespace std;
string& changeSomething(string&& s) {
s[0] = 'a';
return s;
}
int main() {
string s = changeSomething("hello");
cout << s << endl;
}
在这里,我将右值引用传递给函数,并返回对对象的引用。这里的问题是,我认为这会给 UB,因为我将 r 值传递给函数并且它没有分配内存地址,但这会输出:
艾洛
有什么我在这里想念的吗?
解决方案
这不是UB。临时对象在表达式结束之前不会被破坏,您可以在同一个表达式中复制它。要获得基本的第一个想法,您可以使用-fsanitize=address -fsanitize=undefined
. 这并不完美,但有帮助。为了更准确地了解何时调用构造函数/析构函数,您可以从中打印一些内容:
#include <cstdio>
struct Noisy {
char const* data;
Noisy(char const* ch) : data{ch} { std::puts("Noisy()"); }
Noisy(Noisy const& oth) : data{oth.data} { std::puts("Noisy(Noisy const&)"); }
~Noisy() { std::puts("~Noisy()"); }
};
Noisy& changeSomething(Noisy&& s) { return s; }
int main() {
Noisy s = changeSomething("Hello");
std::puts(s.data);
}
输出是:
Noisy()
Noisy(Noisy const&)
~Noisy()
Hello
~Noisy()
你可以看到复制是在销毁之前完成的,所以在销毁之后什么都没有访问。在Compiler Explorer上查看。
推荐阅读
- dask-distributed - 您可以使用从数据已分区的现有 MPI 作业分发的 Dask 吗?
- c++ - std::optional:简单和引用限定值()之间的有效区别
- amazon-web-services - AWS Chalice - 发送文件作为响应
- asp.net-core - Azure Devops 中应用程序和配置设置的语法
- node.js - 如何从 Twitter API 中的 POST oauth/request_token 获得成功响应?
- javascript - 本地存储没有存储多个 slideToggle 的状态
- c - How to convert an int8_t array to int32_t array in C
- python - 如何读取和执行二进制文件?
- shell - 为什么按顺序标记文件夹中的文件会创建额外的文件?
- angular - Angular 7 不会开始导航,没有看到任何错误。关于什么是错的任何提示?