繁体   English   中英

为什么函数返回不移动向量?

[英]Why does function return not move vector?

经过很长时间的C#工作后,我正在使用C ++ 17,并通过一些Euler问题解决了我的问题。 无论如何,任何人都可以解释为什么createRandomVector(const int n)没有“移动”创建的向量吗? 我输出内存地址,并且它们仅在通过引用传递时保持不变(很明显)。 下面是代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <random>

using namespace std;

auto createRandomVector(const int n)
{
    vector<int> v(n);

    iota(begin(v), end(v), 1);
    shuffle(begin(v), end(v), std::mt19937());

    cout << &v << endl;
    return v;
}

void printVector(const vector<int>& v, ostream& os);

int main()
{
    auto v = createRandomVector(100);
    printVector(v, cout);

    cout << endl;

    cout << &v << endl;
    return 0;
}


void printVector(const vector<int>& v, ostream& os)
{
    cout << &v << endl;
    for_each(begin(v), end(v), [&os](auto& i)
    {
        os << i << " ";
    });
}

这是输出:

00BBFC20
00BBFD38
100 73 64 ... 85 90
00BBFD38

为什么第一存储器地址与第二存储器地址不匹配? 我对移动在现代C ++中的工作方式有一些了解(static_cast)。 但是为什么这不起作用?

这里有两个问题:移动和复制省略。

首先,移动: 移动意味着存在两个不同的对象,并且其中一个的内容转移到了另一个。 (与将一个内容复制到另一个内容相反)。 在C ++中,对象在整个生命周期中都有固定的地址。

示例片段:

vector<int> a { 1, 2, 3, 4, 5 };
vector<int> b;
cout << &a << ", " << &a[0] << '\n';
b = std::move(a);
cout << &b << ", " << &b[0] << '\n';

我没有运行此命令,因此希望它没有错别字,但您应该看到,即使两个向量不同, int对象块也已从一个转移到另一个。

如果将&v[0]的输出添加到程序中,则应该会看到相同的效果。


其次, 复制省略 在这种情况下,C ++标准使其成为可选,以便在为main v预留的存储空间中实际创建createRandomVector的局部变量v 在这种情况下,甚至没有任何与return步骤相关的移动或复制操作。

当函数按值返回并且return语句的形式为: return X;可能发生的情况return X; 其中X是没有修饰的局部变量的名称。

如果编译器确实采用了此选项,则程序的前两个输出将是相同的。 显然,您的编译器仅决定在发布模式下执行此操作。

为什么第一存储器地址与第二存储器地址不匹配?

它们是不同的对象,因此不需要它们具有相同的内存地址。

但是,第二个对象可能会重用第一个对象的存储。 这种优化-即构造局部自动变量来代替返回值,从而从局部变量中消除(通过移动)其副本初始化-被称为返回值优化

虽然返回值本身是一个临时值,但在调用范围内还有一个从临时值到局部变量的移动。 此举也可以忽略。 编辑:自C ++ 17起不再适用。

因此,另一种回答你的问题是:由于编译器没有执行 任何 命名返回值优化 ,或者它不从的Elid返回值的举动。 这样的优化不是强制性的,而是由编译器决定是否执行。

在Debug中,我用&v得到了不同的结果,但是在Release模式下,我得到了相同的结果。

对于编译器而言,在调试模式下不执行某些优化是非常典型的。

为什么函数返回不移动向量?

该载体在这个意义上移动 v是移动构造的。 但是看来您通过“移动”还具有其他含义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM