【问题标题】:copy elision using STL (vector as example)使用 STL 复制省略(以向量为例)
【发布时间】:2016-10-09 02:11:04
【问题描述】:

我正在阅读 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&lt;int&gt;(无引用)

还有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)

两者的内存地址不同,所以我在想只要它不会创建复制构造器,最后它就会是相同的内存地址(0xffeffe40)这是否意味着它是复制构造的?

这个方法是复制省略吗?

  • 如果不是:为什么不是复制省略?
  • 如果是:我怎么知道它真的在进行复制省略?

还有一个重要的问题:如果这不是复制省略,有可能做到吗?在 STL 中进行复制省略需要什么?

【问题讨论】:

  • 这个问题不是关于“STL”中的复制省略(无论是什么意思),而是关于用户编写的代码中的复制省略。
  • 改用vector&lt;int&gt; res = merge(arrA, arrB);
  • @SamVarshavchik 谢谢!,就这么说吧。只有当声明与函数调用在同一行时,才会发生复制省略。对吗?
  • 问题是没有副本可以省略。您正在将函数的返回值分配给现有对象。这将调用现有对象的赋值运算符,而不是复制构造函数。

标签: c++ copy-elision


【解决方案1】:

对于复制省略,您首先需要有“复制”,即您的 res 向量必须是从返回值构造的复制。
否则你只会有一个任务,这需要摆脱向量中的任何内容,因此不能省略。

请注意,它仍然是一个移动任务,因此缺点不会太大(您也可以使用 memcheck 对其进行测试)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多