包含字符串的类:当它从函数返回时会发生什么?
Class containing string: what really happens when it's returned from a function?
并不是我不信任我的编译器,而是我想知道发生了什么。假设我有
struct Foo {
std::string s;
};
我想创建其中一个(在堆栈上(,填写很长的字符串,然后从我的函数中返回它。
Foo f() {
Foo foo {my_very_long_string};
return foo;
// OR: return Foo {my_very_long_string};
}
我知道有RVO和移动语义之类的东西;我怎么知道它们正在被使用,并且在运行时它不会在堆上分配带有数据的新字符串,复制它并释放旧的字符串?(除了我的程序会变慢。
是否使用移动构造函数重用字符串数据?还是使用 RVO 实际返回相同的字符串?
NRVO 或移动命名对象
在函数中:
Foo f() {
Foo foo{my_very_long_string};
return foo;
}
对象foo
有一个名称(即:foo
(,它是一个命名对象。
命名 RVO (NRVO( 是一种可选优化,可能会发生。如果没有 NRVO 发生,则foo
被移动,因为它是一个本地对象,因此在此上下文中被视为右值(即:return
语句(。
RVO/复制或移动未命名的对象
但是,在函数中:
Foo f() {
return Foo{my_very_long_string};
}
涉及一个未命名的对象,即由Foo{my_very_long_string}
生成的对象。
从 C++17 开始,必须省略副本(即:与 RVO 相同的效果,尽管语义不同(。
在 C++17 之前,可能会发生 RVO,这在当时是可选的优化。如果没有,则将其移动,因为
Foo{my_very_long_string}
已经是右值。
在上述任何情况下都不会发生新字符串的堆分配。
相关文章:
- 查找不存在的键时,unordered_map返回什么
- 如果我在 const 函数上使用指针,我可以返回什么?
- 使用枚举作为条件,if 条件将返回什么,真或假?
- 我应该返回什么而不是标准::shared_ptr<>&?
- 当你只使用 return 时,函数返回什么类型;在 c++ 中
- 在C++中,运算符 sizeof 返回什么数据类型?
- ActorItr 迭代器变量中有什么,* ActorItr 返回什么?
- mxGetPr 返回什么?
- 重载运算符返回什么类型的值(对于用户定义的类型):右值还是左值?
- 代码是否有效.如果我想显示第一个元素?如果不是,那么 s.begin() 会返回什么?
- 范围分辨率运算符在类型:: var的情况下返回什么
- fork_rv返回什么
- int* foo(int a)在C 中返回什么
- 当找不到请求的注册表值时,ReggetValue会返回什么
- 我们应该在带有 char *func(char *string) 的函数中返回什么?需要简要说明这与 c 中的 char
- 重载的 QAbstractItemModel::flags 应该为无效的 QModelIndex 返回什么
- 试图在每次输出后使用一个函数摆脱'0',但不确定我可以返回什么
- 查找函数在失败结果中应该返回什么
- 当c 中的矢量容器过载[]运算符时,我对未定义的索引返回什么
- 新运营商在组装中返回什么