Hi Everyone,
Some feedback from playing with Boost.Describe for class types.
1. As others pointed out, it is confusing that BOOST_DESCRIBE_STRUCT() and
BOOST_DESCRIBE_CLASS() have such close names, but their interface and
requirements are so different. Maybe rename the latter to
BOOST_DESCRIBE_THIS_CLASS()?
2. Base class subobjects are in some applications treated equivalently to
member subobject; this is why I found it surprising that I cannot get the
names of base class subobjects. But I guess there are implementation
difficulties. Bases can be qualified names.
3. As with enums, _public_member_descriptor_fn in global namespace is UB or
invalid program as per http://eel.is/c++draft/lex.name#3.2.
4. As others pointed out, the part of the interface that uses enum
modifiers is not intuitive. I think that after a while it starts to make
sense: you decide on your use case (like doing RPC), form your enum
bitmask, and then pass it everywhere. It became more-less clear to me only
after I had a look at the implementation of member_filter:
https://github.com/pdimov/describe/blob/develop/include/boost/describe/membe...
Maybe it makes sense to expose this in the docs.
5. Modifier mod_inherited is great for flattening the inheritance structure:
struct X {
int a;
};
struct Y : X {
int b;
};
struct Z : Y {
int c;
};
BOOST_DESCRIBE_STRUCT(X, (), (a));
BOOST_DESCRIBE_STRUCT(Y, (X), (b));
BOOST_DESCRIBE_STRUCT(Z, (Y), (c));
int main() {
namespace desc = boost::describe;
using namespace std::literals::string_literals;
constexpr auto mod = static_castdesc::modifiers(desc::mod_public |
desc::mod_inherited);
using L = desc::describe_members
Andrzej Krzemienski wrote: ...
It even works when base classes have members with same names:
struct X { int a; };
struct Y { int a; };
struct Z : X, Y { int b; }; ... 5. What is the use case for modifier mod_hidden? I cannot think of any situation where I would need it.
If you change the name of `Z::b` above to `a`, it will hide the two `a` members in X and Y, so they won't be included in mod_inherited unless mod_hidden is also passed. Whether you'd want them to be depends on why do you want all the members; when doing RPC you don't want the hidden functions, for instance. But if for some (layout?) reasons you want all the data members, you do want the hidden members.
7. Modifier mod_virtual works unintuitively. It does not affect the filtering in describe_bases<>. It is only used for decorating the list elements. Maybe the docs should be more explicit about what it is used for. Again, is there a use case for this?
mod_virtual is necessary for the implementation of mod_inherited for base classes (virtual bases of the same type must only be returned once.) Since the library has to compute it anyway, I might as well return it to the user. My original design (which was about a compiler implementation of these reflection facilities) had more such output-only "modifiers", such as mod_final and mod_overridden. These, along with mod_virtual, were supposed to be returned in member function descriptors - the compiler knows all this and we can't get it in any other way, so why not return it. In the library implementation, only mod_virtual for bases remained. :-)
Am 14.03.21 um 18:33 schrieb Peter Dimov via Boost:
mod_virtual is necessary for the implementation of mod_inherited for base classes (virtual bases of the same type must only be returned once.)
Since the library has to compute it anyway, I might as well return it to the user.
My original design (which was about a compiler implementation of these reflection facilities) had more such output-only "modifiers", such as mod_final and mod_overridden. These, along with mod_virtual, were supposed to be returned in member function descriptors - the compiler knows all this and we can't get it in any other way, so why not return it. In the library implementation, only mod_virtual for bases remained. :-)
This reminds me of a question I had earlier but forgot: Given C++17
constexpr if I think it would be useful to return ALL members and then
constexpr if on the type.
E.g. currently it is not possible to do:
boost::mp11::mp_for_each
Le 2021-03-15 08:47, Alexander Grund via Boost a écrit :
Am 14.03.21 um 18:33 schrieb Peter Dimov via Boost:
I.e. the problem with the toggles is, that they are toggles only. It is impossible to return both static and not-static members, which especially for functions is useful In general it is impossible to return ALL members, e.g. `boost::mp11::mp_for_each
` could be useful, especially for a compiler implementation
I've been thinking about that, and i believe reversing the modifiers
could give a cleaner interface for doing it. ie, something like:
describe_members
Julien Blanc wrote:
From what I have seen, it may event be built on top of the current describe machinery (there is, i believe, pretty much everything in the details namespace to implement it without touching the macros and the current model).
You can implement any alternative modifiers on top of the current primitives without touching anything in the detail namespace.
participants (4)
-
Alexander Grund
-
Andrzej Krzemienski
-
Julien Blanc
-
Peter Dimov