slavik81 showed a simpler for_each in a comment;
auto for_each = [](R&& r, Fun fun) {
return r | view::transform(fun) | view::join;
};
similarly, it seems that yield_if can also be radically simplified
auto yield_if = []<Semiregular T>(bool b, T x) {
return b ? view::single(x)
: view::empty<T>;
};
But if you actually read the blog post... for_each and yield_if are a part of the range_v3 library and are proposed additions to the language.
Also I don't know what the heck is up with that cout statement; we can use structured declarations to make that look more pythonic too. And there's also a proposal for string formatting [1]
#include "fmt/format.h"
#include <iostream>
#include <ranges>
using namespace std;
using namespace view;
using namespace fmt;
int main() {
auto triples =
for_each(iota(1), [](int z) {
return for_each(iota(1, z+1), [=](int x) {
return for_each(iota(x, z+1), [=](int y) {
return yield_if(x*x + y*y == z*z,
make_tuple(x, y, z));
});
});
});
for(auto [x,y,z] : triples | take(10))
cout << format("{}, {}, {}", a, b, c) << endl;
}
So despite all the protests about how ugly Eric's solution is... I don't think the above is significantly worse than your python & rust equivalents. Speaking as a python evangelist who uses C++ out of nece$$ity.
[1] https://github.com/fmtlib/fmt