使用 C++20 范围展平嵌套 for 循环
Flatten nested for loops with C++20 ranges
有时我需要“双重 for 循环”,因为除了将第一个循环变量传递给内部 for 循环外,我在外部 for 循环中什么也没做,我想知道它是否可以用 C++20 范围优雅地完成。
我想“展平”的嵌套 for 循环示例。
struct Person{
std::string name = "Bjarne";
};
std::vector persons{Person{}, Person{}};
int main() {
for (const auto& person: persons) {
for (const auto& ch: person.name) {
std::cout << ch << std::endl;
}
}
}
我能想到的最好is:
std::ranges::for_each(persons | std::views::transform(&Person::name) | std::views::join, [](const char& ch){
std::cout << ch << std::endl;
});
但是不知道有没有更简单的方法
是的,你的建议是正确的。除了它仍然可以是一个 range-based for 语句,你不必切换到一个算法:
for (const auto& ch : persons
| std::views::transform(&Person::name)
| std::views::join)
{
// ...
}
大多数语言使用名称 map
而不是 transform
,使用 flatten
而不是 join
(事实上,您的问题标题询问的是扁平化)。然后通常将这两者与一个名为 flat_map
的新算法放在一起,该算法将这两件事结合在一起。
我们也能做到:
inline constexpr auto flat_map = [](auto f){
return std::views::transform(f) | std::views::join;
};
for (const auto& ch : persons | flat_map(&Person::name))
{
// ...
}
尽管在 C++ 中我想这会被称为 transform_join
?嗯。 flat_map
一路走来。
Pro-tip: use fmt::print
打印范围,写得少,而且已经格式化了。
有时我需要“双重 for 循环”,因为除了将第一个循环变量传递给内部 for 循环外,我在外部 for 循环中什么也没做,我想知道它是否可以用 C++20 范围优雅地完成。
我想“展平”的嵌套 for 循环示例。
struct Person{
std::string name = "Bjarne";
};
std::vector persons{Person{}, Person{}};
int main() {
for (const auto& person: persons) {
for (const auto& ch: person.name) {
std::cout << ch << std::endl;
}
}
}
我能想到的最好is:
std::ranges::for_each(persons | std::views::transform(&Person::name) | std::views::join, [](const char& ch){
std::cout << ch << std::endl;
});
但是不知道有没有更简单的方法
是的,你的建议是正确的。除了它仍然可以是一个 range-based for 语句,你不必切换到一个算法:
for (const auto& ch : persons
| std::views::transform(&Person::name)
| std::views::join)
{
// ...
}
大多数语言使用名称 map
而不是 transform
,使用 flatten
而不是 join
(事实上,您的问题标题询问的是扁平化)。然后通常将这两者与一个名为 flat_map
的新算法放在一起,该算法将这两件事结合在一起。
我们也能做到:
inline constexpr auto flat_map = [](auto f){
return std::views::transform(f) | std::views::join;
};
for (const auto& ch : persons | flat_map(&Person::name))
{
// ...
}
尽管在 C++ 中我想这会被称为 transform_join
?嗯。 flat_map
一路走来。
Pro-tip: use fmt::print
打印范围,写得少,而且已经格式化了。