Как перебрать все элементы в двух векторах?
Есть два вектора. Нужно перебрать все их элементы и сделать одно и то же действие сначала над элементами одного вектора, потом второго.
std::vector<int> mas1 = {0,1,2,3};
std::vector<int> mas2 = {4,5,6,7,8,9};
for (auto num : mas1) { do_smth (); }
for (auto num : mas2) { do_smth (); }
Можно ли сделать то же самое одним циклом, но не создавая общий вектор?
Ответы (2 шт):
Чтобы избежать повторения do_smth
или содержимого цикла можно итерироваться по view от коллекций (или даже ranges склеить), что не потребует динамического выделения памяти в отличии от создания одного вектора:
auto Make_View(auto & container)
{
return ::std::span{container.begin(), container.end()};
}
...
std::vector<int> mas1 = {0,1,2,3};
std::vector<int> mas2 = {4,5,6,7,8,9};
for (auto & view: {Make_View(mas1), Make_View(mas2)})
{
for (auto & num: view)
{
do_smth ();
}
}
или вообще в лоб итерироваться даже без view:
std::vector<int> mas1 = {0,1,2,3};
std::vector<int> mas2 = {4,5,6,7,8,9};
for (auto & p_view: {&mas1, &mas2})
{
for (auto & num: *p_view)
{
do_smth ();
}
}
std::views::join
- объединяет массив массивов в один длинный длинный виртуальный массив. Проблема в том, что это не может быть массив ссылок (это запрещено), и не может быть массив собственно массивов (требует копирования), но может быть массив виртуальных массивов - просмотровщиков (views) :
int main() {
std::vector<int> mas1 = {0,1,2,3};
std::vector<int> mas2 = {4,5,6,7,8,9};
for( auto num : std::views::join(
std::array{ // array - не требует динамического выделения памяти (размер известен на этапе компиляции)
std::views::all(mas1),
std::views::all(mas2) // std::views::all - тоже что Make_View в ответе ниже
}
)
)
{
std::cout<<num<<std::endl;
}
}