Meh*_*dad 3 c++ rvalue-reference language-lawyer c++11
据我所知,没有R值引用,C++中的完美转发是不可能的.
但是,我想知道:还有什么需要它们吗?
例如,此页面指出了这个示例,其中R值引用显然是必要的:
Run Code Online (Sandbox Code Playgroud)X foo(); X x; // perhaps use x in various ways x = foo();最后一行:
- 破坏所持有的资源
x,- 克隆来自临时返回的资源
foo,- 破坏临时,从而释放其资源.
但是,在我看来,如果swap实施得当,一个简单的改变就能解决问题:
X foo();
X x;
// perhaps use x in various ways
{
X y = foo();
swap(x, y);
}
Run Code Online (Sandbox Code Playgroud)
所以在我看来,r值引用对于这种优化不是必需的.(那是对的吗?)
那么,什么是可能的一些问题不与R值引用来解决(除完美转发,对此我已经知道了)?
Nic*_*las 12
那么,r值引用无法解决的问题是什么(完全转发除外,我已经知道了)?
是.为了使swap技巧起作用(或者至少是最佳地工作),必须将类设计成在构造时处于空状态.想象一个vector实现总是保留一些元素,而不是从完全空的开始.从vector已经存在的默认构造中交换vector将意味着进行额外的分配(在此vector实现的默认构造函数中).
通过实际移动,默认构造的对象可以具有已分配的数据,但移动的对象可以保持未分配状态.
另外,请考虑以下代码:
std::unique_ptr<T> make_unique(...) {return std::unique_ptr<T>(new T(...));}
std::unique_ptr<T> unique = make_unique();
Run Code Online (Sandbox Code Playgroud)
没有语言级别的移动语义,这是不可能的.为什么?因为第二个声明.按照标准,这是复制初始化.顾名思义,这要求类型可以复制.而且重点unique_ptr在于它是独一无二的.IE:不可复制.
如果移动语义不存在,则无法返回.哦,是的,你可以谈论复制省略等等,但请记住:省略是一种优化.符合标准的编译器仍必须检测到复制构造函数存在且可调用; 编译器只是可以选择不调用它.
所以不,你不能只用它来模拟移动语义swap.坦率地说,即使你可以,为什么你会想要?
你必须swap自己编写实现.所以,如果你有一个有6个成员的班级,你的swap职能必须依次交换每个成员.递归遍历所有基类等.
C++ 11(虽然不是VC10或VC2012)允许编译器为您编写移动构造函数.
是的,有些情况下你可以在没有它的情况下离开.但他们看起来非常难以理解,很难理解为什么你这样做,最重要的是,让读者和作者都感到困难.
当人们为了性能而想要做很多事情时会使他们的代码繁琐易读,难以编写,并且易于维护(swap例如,在没有将其添加到函数中的情况下将其他成员添加到类中),那么你就是'重新审视可能应该成为语言一部分的东西.特别是当它是编译器可以很容易处理的东西时.