返回基本类型和结构的本地对象

时间:2016-01-27 14:43:33

标签: c++ reference return-value-optimization

获取对临时变量的引用:

struct S
{
    S() = default;
    S(const S& other) = delete;
    S(S&& other) = delete;

    ~S(){}
};

S foo1()
{
    return {}; // RVO (???)
}

int foo2()
{
    return 42; // RVO
}

int main()
{
    S& i = foo1(); // compiles!
    int& i2 = foo3(); // error C2440: 'initializing' : cannot convert from 'int' to 'int &'
}

我知道使用const说明符的参考生命延期。并且很明显为什么foo2会出错。但为什么foo1有效?

P.S。:用VS2013 / 15进行测试

2 个答案:

答案 0 :(得分:1)

在启用所有警告(/Wall)的情况下进行编译,您偶然会得到以下信息:

  

source_file.cpp(22):警告C4239:使用非标准扩展名:'初始化':从'S'转换为'S&'

答案 1 :(得分:1)

gcc 4.9.3 std = c ++ 14不喜欢任何一个初始化。

如果我们将foo1()更改为

S foo1()
{
    S s;
    return s; 
}

它还抱怨已删除的移动ctor。我不确定为什么原始代码不需要一个。

Cppreference states:“即使发生了复制省略并且没有调用复制/移动构造函数,它也必须存在且可访问(好像根本没有发生优化),否则程序就会生效形成“。

在标准中,12.8 / 32:

  

[注意:无论是否复制,都必须执行此两阶段重载解析   发生。它确定在未执行elision时要调用的构造函数,以及所选的构造函数   即使通话被取消,也必须可以访问。 -end note]

据我所知,这个笔记指的是找到正确的移动(第一次尝试)或复制(第二次尝试)构造函数,而不是另一个。