簡體   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