c – 为什么下面的代码没有断言?
07.在comp.std.c上,Howard Hinnant先生展示了以下代码:
#include <utility> #include <cassert> struct A { A() : data_(1) {} A(A&& a) : data_(a.data_) {a.data_ = 0;} int data_; }; void g(const A&) {} void g(A&& a) {a.data_ = 0;} void h(const A&) {} void h(A&& a) {a.data_ = 0;} void f(A&& a) { g(a); // calls g(const A&) h(a); // calls h(const A&) if (true) { h(a); // calls h(A&&) (by Alexandrescu rules) } } int main() { A a; f(a); assert(a.data_ == 1); } 然后他写道:
使用实际的C 11规则,上面的代码无法编译,因为main()中的左值a不绑定到右值引用.但只是假设它被编译,正如本次讨论发生的情况可能应该这样,我无法理解上面的断言,也就是说,根据N1377规则,它没有断言..根据先前的规则,不会变量a被盗(a.data_ = 0),a作为参数传递给f与f(a)? 解决方法
在C 0x标准中,&&声明专门提到r值参考.评论中的链接以及此链接引用了2006版本.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html 您还可以深入讨论该问题,以及为何在此重要: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html 简而言之,rvalue引用消除了对以下习语的需要: int a = 10; int b = 1000; //Now let's swap them int temp = a; a = b; b = temp; 右值引用允许不涉及创建临时对象的惯用语,并使用50%以上的内存.尽管如此,即使按照我们关心A& A之间差异的旧标准来说也是如此.和A&&,如果你编写合理的代码,使用rvalue引用dissapears,因为任何体面的编译器都可以在标准代码中轻松优化其优势. 老实说,我不知道为什么h(a)调用更改为右值引用,因为它是在if语句的范围内调用的. 编辑:根据评论. 有人提出,变量范围内变量的最终使用应该默认为rvalue版本,因为这是更优化的,并且由这样的引用引起的盗窃并不重要,因为变量很快就会到超出范围. 那么,const A&版本比A&&版.尽管const A&是一种更简洁的类型匹配,A&&版本更快,并且使用它的危险对于左值的最后引用是不存在的. Alexandrescu建议,对于这样的“最终参考”,我们使用rvalue. 然而,Hinnant声明(通过评论),在Alexandrescu建议的修改下,代码没有按预期执行并且抛出断言,但根据当前的n1377规则,使用标准绑定,它不会.揭穿他提议的标准变更. Hinnants的例子表明,这是一个微观优化,规则需要比Alexandrescu建议的更加简洁.而且,因为我们也可以通过引用传递左值,你可以安全地使用这样的右值引用的时间,最终只有一次变量声明,最好是次要优化. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |