自学内容网 自学内容网

RVO C++函数返回值复制优化

来源:https://sigcpp.github.io/2020/06/08/return-value-optimization

简单总结:
函数返回值一般可以触发返回值复制优化,但是有下面几个条件:

  1. 语言支持。目前 GCC 和 MSVC 都默认执行 URVO,并且无法禁用它,因为 C++17 保证在返回临时对象时进行复制省略。
  2. 在接受函数返回值的语句是一个初始化语句(这样RVO才能发挥优势)
/// 触发
S get_name()
{
S s1;
return s1;
}

S get_uname()
{
return S();
}

S s = get_name(); /// 触发RVO
S s1 = get_uname(); /// 触发RVO
/// 不触发
S get_name()
{
S s1;
return s1;
}

S get_uname()
{
return S();
}

S s;
s = get_uname(); /// 失去优势,即使触发了RVO,这里也是assign。

可以通过传入引用的方式/指针用法 避免RVO失去优势

void get_F1(S& s) {
    s.i = 8;
}

S* get_F2() {
    S* ps = new S; // 2. default ctor 2
    ps->i = 8;
    return ps;     // should be freed later
}

int main() {
    S s;           // 1. default ctor 1
    get_F1(s);
    std::cout << s.i << '\n';

    S* ps{ get_F2() };
    std::cout << ps->i << '\n';
    delete ps;     // 3. dtor 2
} // 4. dtor 1
  1. 函数本身不能从不同路径返回命名对象
/// 触发
S get_D1(int x) {
    S s;                // 1. default ctor 1
    if (x % 2 == 0) {
        s.i = 8;
        return s;
    } else {
        s.i = 22;
        return s;
    }
}

/// 不触发 会引起拷贝构造
S get_D2(int x) {
    if (x % 2 == 0) {
        S s1;          // 2. default ctor 2 (or default ctor for s2 below)
        s1.i = 8;
        return s1;
    } else {
        S s2;          // 2. default ctor 2 (or default ctor for s1 above)
        s2.i = 22;
        return s2;
    }
} // 3. copy ctor 3 (either s1 or s2 above); 4. dtor 2

S s = get_D1();// 触发RVO
S s1 = get_D2(); // 不触发RVO 拷贝构造

原文地址:https://blog.csdn.net/switch_JR/article/details/142991473

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!