Boost logo

Boost :

From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2020-10-07 12:48:03


śr., 7 paź 2020 o 12:30 Antony Polukhin <antoshkka_at_[hidden]> napisał(a):

> ср, 7 окт. 2020 г. в 10:59, Andrzej Krzemienski via Boost
> <boost_at_[hidden]>:
> >
> > śr., 7 paź 2020 o 09:22 Rainer Deyke via Boost <boost_at_[hidden]>
> > napisał(a):
> >
> > > On 06.10.20 21:50, Andrzej Krzemienski via Boost wrote:
> > > > struct Person {
> > > > std::string firstName;
> > > > std::string lastName;
> > > > int age;
> > > > };
> > > >
> > > > struct Employee : Person {
> > > > double salary;
> > > > };
> > > >
> > > > struct Prisoner : Person {
> > > > int cellNumber;
> > > > };
> > > > ```
> > > > This (a) avoids duplication, and (b) I have the slicing do exactly
> what I
> > > > need: convert an Employee to a Person. Now, I am disappointed with
> what
> > > > C++17 did to aggregate initialization. My natural expectation would
> be
> > > that:
> > > >
> > > > ```
> > > > Employee e {"Bilbo", "Baggins", 111, 1000.00};
> > > > ```
> > > > Flattens the class hierarchy and initializes each of the four
> members.
> > > > Apparently , the C++ committee has a different vision for it. But I
> have
> > > > noticed that if I changed derivation into aggregation (as I indicated
> > > > earlier), the "flat" part of FPR would do exactly what I needed.
> > >
> > > Does that example really work? My expectation would be that flat
> > > reflection would try to break apart the std::strings, and fail with a
> > > compile-time error because std::string is not an aggregate.
> > >
> > > If it does work, then flat reflection is a lot more useful than I had
> > > initially thought!
> > >
> >
> > The following compiles and outputs "1 2 3 " on my GCC compiler:
> >
> > ```
> > struct A {
> > int x, y;
> > };
> >
> > struct B {
> > A a;
> > int z;
> > };
> >
> > int main()
> > {
> > B b = {{1, 2}, 3};
> > boost::pfr::flat_for_each_field(b, [](auto const& field){ std::cout <<
> > field << " "; });
> > }
> > ```
> >
> > However, when I substitute strings for ints it no longer compiles. I am
> not
> > sure if this is just a bug in the implementation or an inherent
> limitation
> > of this library.
>
> That's an inherent limitation of flat reflection.
> Flat reflection is kind of a legacy - it's the first implemented
> "reflection", and it was working only for PODs. Since early versions
> of PFR new precise ways of reflection were discovered. Moreover,
> precise reflection turned out to be much portable and works on more
> compilers.
>
> > I wonder what is your *primary* motivation for removing it:
> > A. Because it is not implementable in many cases?
> > B. Because there is not enough motivation for it, and people don't
> understand what it is for?
> > C. Because it can be accidentally confused with the "precise" version?
>
> It's rather 'D.' - unlike flat reflection, precise representation work
> in much more cases and on more platforms (MSVC fails to do flat
> reflection)
>

Interesting. I do not understand enough about the implementation to be
making definite statements, but based on my superficial knowledge I expect
that it should be possible to reimplement a "flat" reflection on top of
"precise" one.
1. First you call structure_to_tuple() and you get std::tuple<T1&, T2&,
..., Tn&>
2. For every Tn that is an aggregate type you apply structure_to_tuple()
recursively.
3. Then you potentially get a tuple of nested tuples and you need to
flatten it.

Maybe this is more difficult than it seems at first. You may also run into
different implementation limits.

Maybe someday when I have more free time I will try to write a prototype.

Regards,
&rzej;


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk