On Sat, Jan 15, 2022 at 11:34 PM Peter Dimov via SG7 <sg7@lists.isocpp.org> wrote:
David Rector wrote:
> There is also the matter of a) iteration,

>From my perspective (which is trying to get something
working without being able to patch my own compiler),
one interesting property of using info<__id> is that one
can obtain iteration without having `template for`.

Range-returning functions can just return list<__i1, __i2,
..., __in>, which can then be iterated using fold
expressions (or mp_for_each).

I understand that this is quite contrary to the value-based
"ideology", but it's often more usable. Consider, for
instance, the use case of taking a struct and making a
tuple out of it.


template<class S> auto struct_to_tuple( S const& s )
    return struct_to_tuple_impl(s, members_of(^S));

template<class S, template<auto...> class L, auto... R>
auto struct_to_tuple_impl( S const& s, L<R...> )
    return std::make_tuple( s.*pointer_to( R{} )... );

Of course, it might be possible to implement this with
ease using P1240/P2320 range splicing; if so, it will make
a good example.

Admittedly, not being able to write an "almost normal" for loop over a range of metaobjects for now, is a usability issue but:
a) the template for that David has worked on does solve that and would IMO be quite useful to have.
b) as Peters says there are workarounds and in the end I didn't miss that too much.

Also, in recent years I have seen multiple talks where people recommended using named algorithms like filter, for_each, transform, fold, find_if, etc. whenever possible instead of writing for loops. This both clarifies the intent of the composite algorithm and may give the compiler a chance to do some tricks and optimizations. Such algorithms are easily implementable in an API like mirror.

Another thing is, that an instantiation context is required quite often. Unreflection is pretty common in many use cases (which IMO diminishes the potential performance gains) and also highlights the usability issue, namely IIUC ADL doesn't kick in and much more of full name qualification is required,

when  composing functions like:
meta::info foo<meta::info>();
meta::into bar<meta::info>();
meta::into baz<meta::info>();
into algorithms it looks like:


with functions taking something like info<__id>:
auto foo(metaobject auto mo);
auto barmetaobject auto mo);
auto baz(metaobject auto mo);
they compose more nicely:


and this also allows to write nicer placeholder expressions like:

auto my_algo = foo(bar(baz(_1)));

There are many examples (and I have some more in the pipeline) of this here :