Date: Tue, 17 Nov 2020 11:45:30 +0100
Just a question to the C++ experts.
There are some std algorithms that tend to be much more verbose and
unclear than the plain loop counterpart. For example, compare:
for (std::size_t i = 0; i < v.size(); ++i)
u[i] = v[i] / std::sqrt(w[i]);
with:
std::transform(v.begin(), v.end(), w.begin(), u.begin(), [](auto a,
auto b) { return a / std::sqrt(b); });
The introduction of ranges library was a significant improvement:
std::ranges::transform(v, w, u.begin(), std::divides{}, {}, [](auto b)
{ return std::sqrt(b); });
Furthermore, thanks to the current and forthcoming range adaptors,
we'll be able to use algorithms in pieces of code that weren't
previously easily expressible with them. For example:
for (std::size_t i = 0; i < v.size(); ++i)
u[i] = v[i] * y[i] / std::sqrt(w[i]);
might be written:
std::ranges::transform(std::views::zip(v, w, y), u.begin(), [](auto
&&Proxy) { auto [a, b, c] = Proxy; return a * b / std::sqrt(c); });
The question is: would it be theoretically possible to add overloads
to the algorithms such that they accept n-ary callables for iterators
with tuple-like iter_reference_t, where n is
tuple_size<iter_reference_t>?
I mean:
std::ranges::transform(std::views::zip(v, w, y), u.begin(), [](auto a,
auto b, auto c) { return a * b / std::sqrt(c); });
or also:
map<string, int> m;
auto sum = std::ranges::accumulate(m, 0, {}, [](auto &, auto i) { return i; });
though in this case we'd also have:
auto sum = std::ranges::accumulate(m | std::views::values, 0);
Are there cases in which adding such overloads would cause ambiguities?
Pili
There are some std algorithms that tend to be much more verbose and
unclear than the plain loop counterpart. For example, compare:
for (std::size_t i = 0; i < v.size(); ++i)
u[i] = v[i] / std::sqrt(w[i]);
with:
std::transform(v.begin(), v.end(), w.begin(), u.begin(), [](auto a,
auto b) { return a / std::sqrt(b); });
The introduction of ranges library was a significant improvement:
std::ranges::transform(v, w, u.begin(), std::divides{}, {}, [](auto b)
{ return std::sqrt(b); });
Furthermore, thanks to the current and forthcoming range adaptors,
we'll be able to use algorithms in pieces of code that weren't
previously easily expressible with them. For example:
for (std::size_t i = 0; i < v.size(); ++i)
u[i] = v[i] * y[i] / std::sqrt(w[i]);
might be written:
std::ranges::transform(std::views::zip(v, w, y), u.begin(), [](auto
&&Proxy) { auto [a, b, c] = Proxy; return a * b / std::sqrt(c); });
The question is: would it be theoretically possible to add overloads
to the algorithms such that they accept n-ary callables for iterators
with tuple-like iter_reference_t, where n is
tuple_size<iter_reference_t>?
I mean:
std::ranges::transform(std::views::zip(v, w, y), u.begin(), [](auto a,
auto b, auto c) { return a * b / std::sqrt(c); });
or also:
map<string, int> m;
auto sum = std::ranges::accumulate(m, 0, {}, [](auto &, auto i) { return i; });
though in this case we'd also have:
auto sum = std::ranges::accumulate(m | std::views::values, 0);
Are there cases in which adding such overloads would cause ambiguities?
Pili
Received on 2020-11-17 04:45:44