使用STL复制省略(以矢量为例)

copy elision using STL (vector as example)

本文关键字:STL 复制省 使用      更新时间:2023-10-16

我正在阅读c++中的复制省略。我对c++中的STL使用这个复制省略有疑问。

以下代码:

#include <vector>
#include <iostream>
using namespace std;
vector<int> merge(vector<int> &arrA, vector<int> &arrB)
{
    int x;
    vector<int> result;
    for(x = 0; x < arrA.size(); x++)
    {
        result.push_back(arrA[x]);
    }
    for(x = 0; x < arrB.size(); x++)
    {
        result.push_back(arrB[x]);
    }
    cout << "fun return: " << &result <<endl;
    return result;
}

int main(int argc, char const *argv[])
{
    vector<int> arrA;
    arrA.push_back(1);
    vector<int> arrB;
    arrB.push_back(2);
    vector<int> res;
    res = merge(arrA, arrB);
    cout << "return: "  << &res <<endl;
    return 0;
}

所以我正在做一个简单的任务(合并)向量a和B(不注意过程,只是函数和返回)。

vector<int> merge(vector<int> &arrA, vector<int> &arrB)

使用下面的定义,它返回一个vector<int>(没有引用)

还有return result;,它是在函数作用域中声明的变量。

我试图看到这些向量所在的内存地址。输出:

==5036== Memcheck, a memory error detector
==5036== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5036== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==5036== Command: ./a.out
==5036== 
fun return: 0xffefffe40
return: 0xffefffe20
==5036== 
==5036== HEAP SUMMARY:
==5036==     in use at exit: 0 bytes in 0 blocks
==5036==   total heap usage: 5 allocs, 5 frees, 28 bytes allocated
==5036== 
==5036== All heap blocks were freed -- no leaks are possible
==5036== 
==5036== For counts of detected and suppressed errors, rerun with: -v
==5036== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

内存地址是不同的,所以我认为,只要它不会做一个复制构造器,它将是相同的内存地址在结束(0xffefffe40)这是否意味着它是复制构造?

这个方法是复制省略吗?

  • 如果没有:为什么不复制省略?
  • 如果是:我怎么知道它真的在做拷贝省略?

重要的一点是:如果这不是复制省略,是否有可能这样做?在STL中做拷贝省略需要什么?

对于复制省略,您首先需要有"复制",即您的res向量必须从返回值复制构造。
否则,你只是做了一个赋值操作,而赋值操作需要去掉vector中的任何内容,因此不能省略。

注意,它仍然是一个move赋值,所以缺点不会太大(您也可以使用memcheck进行测试)。