c – const引用的临时寿命延长

C

我试图看看const引用如何延长临时工的寿命.我在one of the answers to What are the differences between pointer variable and reference variable in C++?中运行了代码片段中的代码,并且在VC11和g 4.8之间得到了相互矛盾的结果.我在这里扩展了片段:

#include <stdio.h>

struct scope_test
{
    ~scope_test() { printf("scope_test done!\n"); }
};

int main()
{
    const scope_test& test = scope_test();
    printf("in scope\n");
}

回答者得到了结果:

in scope
scope_test done!

我在VC11中试过它并得到了这个:

scope_test done!
in scope
scope_test done!

我假定VC11结果因缺少复制省略引起的,所以我想看看是否与FNO-的Elid-构造摹禁止复制省略将给予相同的结果VC11. (我不认为复制省略可以在VC11中切换.)但是,无论标志的设置如何,g都会给出回答者的结果.

C 11标准,ISO / IEC 14882:2011(E),§12.2/ 4和/ 5规定:

There are two contexts in which temporaries are destroyed at a
different point than the end of the full-expression…

The second context is when a reference is bound to a temporary. The
temporary to which the reference is bound or the temporary that is the
complete object of a subobject to which the reference is bound
persists for the lifetime of the reference except:

VC11结果与copy elision有什么关系吗?它是VC11的错误吗?

回答者说:

temporaries assigned to const references live until the const
reference goes out of scope

§12.2/ 5的例外列表不排除非const引用.我在标准中缺少什么?

删除VC11中的const会产生与带有const的VC11相同的结果.删除g中的const会产生错误:从’scope_test’类型的右值开始,无效初始化’scope_test&’类型的非const引用.为什么会有区别?

编辑:

我添加了复制和移动构造函数并尝试:

#include <stdio.h>

struct scope_test
{
    scope_test() { printf("regular ctor\n"); }
    scope_test(const scope_test& src) { printf("copy ctor\n"); }
    scope_test(scope_test&& src) { printf("move ctor\n"); }
    ~scope_test() { printf("scope_test done!\n"); }
};

int main()
{
    const scope_test& test= scope_test();
    printf("in scope\n");
}

无论复制省略的切换如何,g都给出:

regular ctor
in scope
scope_test done!

VC11给出了相同的东西,即使删除了const.如果从g中删除const,g仍然会给出错误:从’scope_test’类型的右值开始,无效初始化’scope_test&’类型的非const引用.

最佳答案 这两种行为都是正确的,当然根据C 03标准(8.5.3 [dcl.init.ref]第5段):

Otherwise, the reference shall be to a non-volatile const type (i.e., cv1 shall be const). [Example: …]

  • If the initializer expression is an rvalue, with T2 a class type, and “cv1 T1” is reference-compatible with “cv2 T2,” the reference is bound in one of the following ways (the choice is implementation-defined):

    — The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.

    — A temporary of type “cv1 T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.

我认为C 11的定义仍然允许复制,但措辞并不明确允许复制.无论如何,VC并不声称完全符合C 11标准.

点赞