复制-删除返回的自动变量
Copy-elision of automatic variable for return
我想知道是否在c++ 0x "12.8复制和移动类对象[class。当复制省略发生时,确切地说:
现在我想知道,这是否允许在下面的代码中避免复制当满足某些条件时,允许实现省略类对象的复制/移动构造[…]。拷贝/移动的省略在以下情况下,允许进行称为复制省略的操作[…]:
- 在具有类返回类型的函数的返回语句中,当表达式是一个非易失性自动对象的名称时[…]]与函数返回类型相同的cv-不限定类型,可以通过构造来省略复制/移动操作将自动对象直接转换为函数的返回值
- […]
vector<string> gen(const char *fn) {
if(fn == nullptr) // this should prevent RVO
return {"House", "Horse", "Hen"};
vector<string> res;
fillFromFile(res, fn);
return res; // copy elision possible?
}
int main() {
vector<string> data = gen("users.dat");
}
或者这个规则不适合这个例子,我必须显式地写出来吗?
return move(res); // explicitly prevent copy
请注意,我的if
的意图是消除明显的返回值优化 (RVO)。
还是我完全搞错了方向?有一个涉及return
和move的变化,可以使用右值引用,对吧?
是的,在这两种情况下都可以/允许复制省略。
在编译器术语中,这两种情况略有不同。return {"House", "Horse", "Hen"};
构造了一个未命名的对象,所以常规的RVO开始了。
return res;
稍微复杂一些,因为您返回的是之前已经构造好的命名对象。这种优化通常被称为NRVO(命名返回值优化),编译器实现它的情况略少。
MSVC总是实现RVO,并且在发布版本中执行NRVO。
我相信最近版本的GCC总是同时执行RVO和NRVO。
顺便说一下,我真的不明白为什么你的"如果"会对RVO产生影响。
是的,在这种情况下,编译器有特定的指令将res
视为右值,并且res
将被移到data
中。当然,编译器可以很容易地在这里应用RVO/NRVO,因为它可以静态地确定您永远不会使用nullptr
调用该函数,此外,该函数可以进行简单的转换,以便即使无法证明也可以应用RVO/NRVO,最后,这甚至不妨碍RVO/NRVO,因为结果仍然可以在。
相关文章:
- 你能重载对象变量名本身返回的内容吗
- 如何在 c++ 中让布尔变量返回为 0 或 1 而不是真或假?
- 从私有成员变量的成员方法返回unique_ptr
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- C++ 根据给定的类型名从变量返回数据
- 为什么 std::isnan() 对于具有 NAN 值的双变量返回 false
- C++ 在静态函数中使用非静态变量返回类实例
- 具有变量返回类型的函数
- 带有 QVariant 和模板的变量返回类型
- getenv() 在不同的程序中为同一环境变量返回不同的值
- C 多重继承,虚拟方法覆盖问题和协变量返回类型
- 变量返回类型
- C++函数向字符串变量返回int
- 从临时变量返回的引用是否有效
- 有没有一种方法可以将C++数据类型作为变量返回
- 类函数的模板变量返回类型
- C++函数,使用'auto'变量返回类型
- 如何将引用变量返回到函数中
- 变量返回类型上转换覆盖c++
- 数组变量返回意外值