簡體   English   中英

std :: copy_n不會更改目標向量大小

[英]std::copy_n doesn't change destination vector size

如果我為一個向量保留一些空間,然后用std::copy_n()復制其中的一些值,我得到正確復制和可訪問的值,但向量的大小仍為零。 這是預期的行為嗎? 我應該調整矢量大小,即使它沒有效率嗎?

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    std::vector<double> src, dest;

    for(double x = 0.0; x < 100.0; ++x)
        src.push_back(x);

    dest.reserve(src.size());

    std::copy_n(src.cbegin(), src.size(), dest.begin());

    std::cout << "src.size() = " << src.size() << std::endl;
    std::cout << "dest.size() = " << dest.size() << std::endl;

    for(size_t i = 0; i < src.size(); ++i)
        std::cout << dest[i] << "  ";

}

編譯器測試:clang,gcc,Visual C ++

但是矢量的大小仍然為零

std::copy_n不會改變容器的大小,只需復制值並逐步執行迭代器; 它甚至沒有關於容器的任何信息。 因此代碼具有未定義的行為,即使它似乎工作正常。

我應該調整矢量大小,即使它沒有效率嗎?

是的,您可以使用std::vector::resize而不是std::vector::reserve來解決問題。 正如您可能想到的那樣,這意味着將首先通過resize來構造所有元素,然后通過copy_n進行分配。

您可以使用std :: back_inserter ,它將通過調用容器的push_back()成員函數(即直接構造元素)將元素附加到容器的末尾,從而增加容器的大小。 例如

dest.reserve(src.size());
std::copy_n(src.cbegin(), src.size(), std::back_inserter(dest));

關於標准庫算法要記住的關鍵是它們在范圍而不是容器上運行。 容器是您可以創建范圍的方法之一,但它們不是唯一的方法。 將結果寫入范圍的算法假定它們寫入有效位置; 他們沒有,也不能,擴大他們寫作的范圍。

所以當你調用std::copy_n你必須提供一個足夠大的范圍來保存結果。 這意味着使用dest.resize(src.size());設置范圍dest.resize(src.size()); ,而不僅僅是使用dest.reserve(std.size());分配內存dest.reserve(std.size());

或者,您可以通過使用std::back_inserter(dest)而不是dest.begin()調用算法來提供一個知道它附加到容器並需要調整大小的dest.begin()

std :: vector具有大小容量 它保留了比插入更快更多所需的空間。 reserve使您可以指定該容量,而調整大小會更改矢量的實際大小。

你調用reserve ,你的dest分配內存來存儲元素,但它不調用構造函數,它實際上是空的,所以你的代碼會導致UB。 使用resize實際創建這些元素然后就可以了。

dest.resize(src.size());
std::copy_n(src.cbegin(), src.size(), dest.begin());

std::cout << "src.size() = " << src.size() << std::endl;
std::cout << "dest.size() = " << dest.size() << std::endl;

for(size_t i = 0; i < src.size(); ++i)
    std::cout << dest[i] << "  ";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM