假設我在編譯時有一個已知大小的std::vector
,我想將它變成std::array
。我會怎麼做?有沒有一個標準的功能來做到這一點?std :: vector用於std :: array初始化
我迄今爲止最好的解決辦法是這樣的:
template<class T, std::size_t N, class Indexable, std::size_t... Indices>
std::array<T, N> to_array_1(const Indexable& indexable, std::index_sequence<Indices...>) {
return {{ indexable[Indices]... }};
}
template<class T, std::size_t N, class Indexable>
std::array<T, N> to_array(const Indexable& indexable) {
return to_array_1<T, N>(indexable, std::make_index_sequence<N>());
}
std::array<Foo, 123> initFoos {
std::vector<Foo> lst;
for (unsigned i = 0; i < 123; ++i)
lst.push_back(getNextFoo(lst));
return to_array<Foo, 123>(lst); // passing lst.begin() works, too
}
應用類似於Populate std::array with non-default-constructible type (no variadic templates):我也有一個類型,是不是默認 - 構造的,所以我需要計算的實際值數組被初始化。然而,與這個問題相反,對我來說,價值觀不僅僅是指數的函數,而且也是前面的值。我可以使用循環比一系列函數調用更容易地構建我的值。所以我構建了一個循環中的元素並將它們放入一個向量中,然後我想使用該向量的最終狀態來初始化該數組。
上述似乎編譯和工作正常,但也許有辦法來改善它。
- 也許我可以巧妙地使用一些我不知道的標準庫功能。
- 也許我可以以某種方式避免助手功能。
- 也許我可以用某種方式來表達它,以便它可以與元素的移動語義而不是上面使用的複製語義一起工作。
- 或許我能避免使用
operator[]
隨機訪問,而是使用前向迭代語義只所以會爲std::set
或std::forward_list
作爲輸入工作,太。 - 也許我應該停止使用
std::vector
,而是用std::array<std::optional<T>, N>
代替使用C++ 17或某些等效實現來表達我的目標。
相關問題:
- Copy std::vector into std::array不假設一種類型沒有默認的構造函數,所以默認初始化後的複製是可行的,但存在不適合我。
- Populate std::array with non-default-constructible type (no variadic templates)它獨立地從它的索引計算每個元素,所以它試圖避免一箇中間容器。即使標題請求避開它們,解決方案仍然使用可變參數模板。
有趣的問題,但這味道不好。爲什麼只想生成數據然後複製它們?這是你希望將它們打包在'std :: array'中的強制條件,但與原始的'std :: vector'相比,它的優點是什麼?兩者都將數據保存在連續的內存中,因此前者不應該佔用後者的優勢。唯一的區別是'size'是一個編譯時變量,但無論如何也是如此。 – Walter
@Walter:有效的問題。一方面,我的原始是'std :: set',所以我至少需要轉換一次。而且我正在使用轉換構造函數來爲元素執行類型轉換。所以這不是隻保留'std :: vector'的問題。不過,我可以使用一個。主要反對意見可能是我的感覺,越是編譯器知道,它可以優化得越好。我在練習中只處理了24個元素,雖然這對於完整的循環展開來說可能太多了,但它可以例如知道計數可以被4整除,只是一種感覺。 – MvG