[英]How to print out the contents of a std::vector with 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.