C ++返回值优化 [英] C++ return value optimization

查看:203
本文介绍了C ++返回值优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码:

#include <vector>

std::vector<float> getstdvec() {
    std::vector<float> v(4);

    v[0] = 1;
    v[1] = 2;
    v[2] = 3;
    v[3] = 4;

    return v;
}

int main() {
    std::vector<float> v(4);

    for (int i = 0; i != 1000; ++i)
    {
        v = getstdvec();
    }
}



我这里不正确的理解是函数getstdvec shouldn'不得不实际分配它返回的向量。当我运行在valgrind / callgrind,我看到有1001调用malloc; 1用于main中的初始向量声明,每个循环迭代为1000。

My incorrect understanding here is that the function getstdvec shouldn't have to actually allocate the vector that it's returning. When I run this in valgrind/callgrind, I see there are 1001 calls to malloc; 1 for the initial vector declaration in main, and 1000 for every loop iteration.

什么给了?如何从这样的函数返回向量(或任何其他对象),而不必每次都分配?

What gives? How can I return a vector (or any other object) from a function like this without having to allocate it every time?

编辑:我知道我可以通过通过引用的向量。我的印象是,有可能(甚至更喜欢)编写一个这样的函数,返回一个对象,而不会产生不必要的分配。

edit: I'm aware I can just pass the vector by reference. I was under the impression that it was possible (and even preferable) to write a function like this that returns an object without incurring an unnecessary allocation.

推荐答案

当你调用一个函数时,对于返回类型如 std :: vector< T> ,编译器为返回的对象提供内存。被调用函数负责构造在该内存槽中返回的实例。

When you call a function, for a return type like std::vector<T> the compiler provides memory for the returned object. The called function is responsible for constructing the instance it returns in this memory slot.

现在,RVO / NRVO允许编译器省略创建本地临时对象,从内存槽中返回值,破坏临时对象,最后返回调用者。相反,被调用函数直接在返回槽的内存中直接构造局部对象,并且在函数的结尾处,它只是返回。

The RVO/NRVO now allows the compiler to omit creating a local temporary object, copy-constructing the returned value in the memory slot from it, destructing the temporary object and finally returning to the caller. Instead, the called function simply constructs the local object in the return slot's memory directly and at the end of the function, it just returns.

从调用者的角度来看, transparent:它为返回的值提供内存,当调用返回的函数时,有一个有效的实例。调用者现在可以使用此对象,并负责调用析构函数并稍后释放内存。

From the caller's perspective, this is transparent: It provides memory for the returned value and when the function called returned, there is a valid instance. The caller may now use this object and is responsible for calling the destructor and freeing the memory later on.

这意味着RVO / NRVO仅在调用函数来构造一个新的实例,而不是当你分配它。下面是可以应用RVO / NRVO的示例:

This means that the RVO/NRVO only work for when you call a function to construct a new instance, not when you assign it. The following is an example of where RVO/NRVO could be applied:

std::vector<float> v = getstdvec();

但原始代码使用循环,在每次迭代中,结果从需要构造getstdvec(),并将此临时分配给 v 。没有办法,RVO / NRVO可以删除这个。

but you original code uses a loop and in each iteration, the result from getstdvec() needs to be constructed and this temporary is assigned to v. There is no way that the RVO/NRVO could remove this.

这篇关于C ++返回值优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆