C++ Logo

sg7

Advanced search

Re: Scalable reflection - questions / comments

From: Barry Revzin <barry.revzin_at_[hidden]>
Date: Tue, 1 Feb 2022 01:05:28 -0600
I'm not an author of P1240, but...

On Tue, Feb 1, 2022 at 12:24 AM Matus Chochlik via SG7 <sg7_at_[hidden]>
wrote:

> Hi,
>
> I have the following questions about P1240R2:
>
> 1) std::info::meta and ADL
>
> int main() {
> using std::meta; // is either this
> using std::meta::is_named; // or this necessary
> if constexpr (is_named(^int)) { // for this to compile?
> }
> }
>

ADL still works on std::meta::info, so is_named(^int) is valid by itself.


>
> 2) is it / will it be possible for the "filters" in members_of to be
> lambdas or other boolean-returning callables?
>

I think that's the point, yeah. As opposed to?


>
> 3) I have found that there are many use-cases (implementing RPC
> boilerplate, implementing SQL generator, implementing the factory pattern,
> and more) where there is a set of functions like foo, bar, baz that are
> calling each other, which operate on `reflections` (of base-level "things"
> that are not reified on the base level, like a constructor, a namespace, an
> expression) that are passed from outside to the algorithm, and
> splicing is done in the innermost function.
> pseudocode:
>
> auto baz(metaobject auto mo) {
> return do_something([: mo :]);
> }
>
> auto bar(metaobject auto mo, auto arg1, auto arg2) {
> return baz(transform1(transform2(mo, arg2), arg1);
> }
>
> auto foo(metaobject auto mo, auto arg1, auto arg2. auto arg3) {
> return bar(transform3(mo, arg3));
> }
>
> cout << foo(^std, 1, '2', "3");
>
> Is it correct that the only way to do this with meta info is to pass the
> metaobject in template arguments?
>

Can you provide a more real example?


>
> template <std::meta::info mo> auto baz() {
> return do_something([: mo :]);
> }
> template <std::meta::info mo> auto bar(auto arg1, auto arg2) {
> return bar<transform1<transform2<mo>(arg2)>(arg1)>();
> }
> template <std::meta::info mo> auto foo(auto arg1, auto arg2, auto arg3) {
> return bar<transform3<mo>(arg3)>(arg1, arg2);
> }
>
> cout << baz<^std>(1, '2', "3")
>

I suppose the real question is: Does this work?

consteval auto f(std::meta::info type) {
    return sizeof([:type:]);
}

And the answer is no: in the paper, [: refl:] is only valid if refl is a
constant expression. Which, until we get constexpr function parameters,
means it must be passed as a template parameter.


>
> Comments:
>
> I agree that performance or reflection API is important, and I agree that
> the fundamental primitive reflection operations like name_of, etc. should
> be value-based consteval functions (or maybe builtins). However I think
> that we are sacrificing usability, readability and the possibility to write
> a library of complex reflection algorithms (see q.3 above) just for some
> increase in performance, if the only representation of metaobjects is
> std::meta::info.
>
> I'd also suggest doing compile-time measurements and comparisons with
> other approaches on *real-life* use-cases (I don't think that simple
> programs will do 10k+ reflection operations) and in larger programs the
> cost of reflection will typically be only a small fraction of the
> compilation time.
> --
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
>

Received on 2022-02-01 07:05:42