“移动省略”在C 17中得到保证了吗?让我解释一下我的意思。在几乎每一篇关于C 17介绍的文章中,都可以找到一个术语:“RVO的保证复制省略”,这有点不言自明。但是移动构造呢?
让我们看看下面的代码,很简单,有一个不可复制的类型,和两个函数,一个通过值获取不可复制的参数,第二个通过右值引用获取。
#include <iostream>
struct NonCopyable
{
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable(NonCopyable&& other) noexcept
{
std::cout << "Move ctor\n";
}
};
void func_by_value(NonCopyable cp)
{
auto x = std::move(cp);
}
void func_by_rvalue_ref(NonCopyable&& cp)
{
auto x = std::move(cp);
}
int main()
{
std::cout << "Pass by value:\n";
func_by_value(NonCopyable());
std::cout << "\nPass by rvalue_ref\n";
func_by_rvalue_ref(NonCopyable());
}
我使用以下标志使用GCC(主干)编译了两次,结果略有不同。
(1)-O0-std=c 11-fno-elide构造函数
Program output: Pass by value: Move ctor Move ctor Pass by rvalue_ref Move ctor
(2)-O0-std=c 17-fno-elide构造函数
Program output: Pass by value: Move ctor Pass by rvalue_ref Move ctor
所以我的问题是-使用C 17时省略了移动收缩有什么变化?编译器资源管理器
由于引入了C 17强制省略复制/移动操作:
在以下情况下,要求编译器省略类对象的复制和移动构造,即使复制/移动构造函数和析构函数有可观察到的副作用。对象被直接构造到存储中,否则它们将被复制/移动到存储中。复制/移动构造函数不需要存在或可访问:
>
...
在对象的初始化中,当初始化表达式是与变量类型相同的类类型(忽略cv限定)的正则表达式时:
T x = T(T(f())); // only one call to default constructor of T, to initialize x
在从prvalueNonCopyable()
初始化参数cp
时,需要省略移动构造。请注意,强制复制省略适用于复制操作和移动操作。