I played around with C++17/C++1z features apply
and invoke
a bit
Ultimately I wanted to use apply
to the result of equal_range
directly
like this:
cout << apply(std::distance, data.equal_range(4)) << '\n';
That did not compile. I thought It was because equal_range
returned a pair
and not a tuple
but as it turns out, that is not the case.
My larger example compiles everything if I use a Lambda instead of std::distance
. When thinking about the reason for that I assume it has something to do with instantiating the template function distance
. Hrm, a pity that this does not work without it, because I would have a hard time instantiating it with `std::distance::iterator>
#include <iostream>
#include <set>
#include <functional> // invoke
#include <experimental/tuple> // apply
using std::set; using std::cout;
using std::invoke;
using std::experimental::apply;
int main() {
set<int> data { 1,2,3,4,5,6 };
// the C++11-way, not possible in one line.
auto r = data.equal_range(4);
cout << std::distance(r.first, r.second) << '\n';
#if 0 // do not work
cout << invoke(std::distance, r.first, r.second) << '\n';
cout << apply(std::distance, r) << '\n';
cout << apply(std::distance, make_tuple(r.first, r.second)) << '\n';
cout << apply(std::distance, data.equal_range(4)) << '\n';
#endif
// explicitly instantiate distance: intolerably cumbersome
cout << apply(std::distance<set<int>::iterator>, data.equal_range(4)) << '\n';
// using a lambda: too long for a single line
auto d = [](auto b, auto e) { return std::distance(b, e); };
cout << invoke(d, r.first, r.second) << '\n';
cout << apply(d, r) << '\n';
cout << apply(d, make_tuple(r.first, r.second)) << '\n';
cout << apply(d, data.equal_range(4)) << '\n';
}
Is there a nicer, more compact way to use apply
and invoke
with template functions like distance
without explicit instantiation or lambda?