[英]Easy way to iterate through multiple std::vectors in C++
我有兩個相同類型的std::vector
,我需要使用相同的例程遍歷它們。 像這樣:
std::vector<int> values1, values2;
int counter = 0;
for (int val : values1) counter += val;
for (int val : values2) counter += val;
有什么簡單的方法可以在一個循環中編寫最后兩行,以避免代碼重復? 看起來像這樣的東西:
std::vector<int> values1, values2;
int counter = 0;
for (int val : values1, values2) counter += val;
如果在迭代它們之后不需要訪問任何一個向量,則可以將它們移動到std::initializer_list
中,然后對其進行迭代:
std::vector<int> values1{1, 2, 3};
std::vector<int> values2{4, 5, 6};
for (const auto& v : {std::move(values1), std::move(values2)}) {
for (auto value : v) {
std::cout << value << ' ';
}
}
// prints "1 2 3 4 5 6 "
正如 ShadowRanger 在下面指出的那樣,如果我們迭代std::reference_wrapper
的初始化列表,則不需要從原始向量移動。 這可以通過將std::move
與std::cref
交換(或std::ref
如果你需要改變它們)來完成:
for (const auto& v : {std::cref(values1), std::cref(values2)}) {
for (auto value : v.get()) {
std::cout << value << ' ';
}
}
// prints "1 2 3 4 5 6 ", as before
不,沒有,抱歉。 至少不是直接用語言。
for (int val : boost::range::join(values1, values2))
counter += val;
因為 Boost 可以做到這一點,所以您也可以通過制作自己的迭代器類型來對 collections 投射“視圖”。
但是,特別是在您展示的簡單案例中,通常不值得。 如果您的循環體更復雜,我建議將其拆分為采用int
的 function。 這可以只是在循環上方聲明的 lambda。 我就是做這個的。
使用 range-v3 你可以這樣寫:
namespace rs = ranges;
namespace rv = ranges::views;
int counter = rs::accumulate(rv::concat(values1, values2), 0);
我懷疑 C++23(或 C++2b)將對此提供庫支持。 所需要的只是一個范圍適配器views::concat
和<numeric>
header 的范圍化。
怎么樣:
std::vector<int> values_vecs[2];
// ...
int counter = 0;
for (const auto& values : values_vecs)
for (int val : values) counter += val;
它與您的原始代碼不完全相同,但它可以輕松支持 2 個以上的向量。
如果向量已經作為兩個單獨的向量存在,您仍然可以使用 go:
std::vector<int> values1, values2;
//...
int counter = 0;
for (auto values_ptr : {&values1, &values2})
for (int val : *values_ptr) counter += val;
我使用類似這樣的方法遍歷 3 個不同大小的向量,其中一個向量依賴於其他兩個向量(first_vector 依賴於其他向量)。
#include <iostream>
#include <vector>
int main() {
std::vector<int> first_vector{50, 20, 30, 5000};
std::vector<int> second_vector{10};
std::vector<int> third_vector{500, 10};
for (int i = 0, j = 0, k = 0; i < first_vector.size(); ++i, ++j, ++k) {
if (j == second_vector.size()) {
j = 0;
}
if (k == third_vector.size()) {
k = 0;
}
std::cout << first_vector[i] << '|' << second_vector[j] << '|'
<< third_vector[k] << '\n';
std::cin.get();
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.