-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] Multiple T data members before this data member
#334
Comments
|
For I think, in general, |
|
Right, the next thing I wanted to add was a disambiguator for exactly that case... hold on... |
|
(I meant to do that before pushing this commit... I knew there was one thing I'd forgotten...) |
|
Actually the idea I had in mind is simpler... move the |
|
@hsutter So, from what I understand, if I declare a member before a base type, the member will be put into As this is perfectly fine (especially when the name will be added as a template parameter) I am curious about what is behind that idea. Is there any rule that covers that or is it just an enabler for something else? |
|
Done -- BTW @JohelEGP I didn't know about Boost's So I think Cpp2 now allows both examples from that page's documentation, but expressed directly. This is pretty nice, here's how I understand it (please correct, I didn't compile the following code so it may have typos/thinkos)... Example 1: Single objectIn the Boost example, the first motivating example looks like this, where you need to initialize the output Today, using BoostCpp2 equivalentAs of today's cppfront commits that add inheritance, and allow ordering member and base subobjects interleaved and accessing them all by name, in Cpp2 you just write the (data/base) members in the desired order and use their names directly: Example 2: Multiple objectsHere's the second example from that Boost page, which shows a little state machine: Today, using BoostCpp2 equivalentIf I understand the Boost example correctly, the equivalent in Cpp2 as of today is now this (modulo typos): Nice, thanks for the Boost link. |
Yes. The latter half of the sentence is an implementation detail -- from the point of view of the user, they simply wrote the data member subobject before the base subobject, which not only guarantees they are laid out in that order but also guarantees that the data member is initialized (constructed) before the base class.
See the above examples (thanks again for the Boost page link @JohelEGP!)... it doesn't come up a lot, but sometimes there is a need to initialize a base class with a data member, and they'd better be constructed in the right order. I knew workarounds for this existed, but I didn't know Boost had one, and that what I just checked in pretty much mirrored the Boost implementation (wow... because I considered several different implementations and decided the private wrapped base one was best, and lo and behold! Daryle Walker, the author of this Boost library, made the same decision -- thanks Daryle!). Also, pasting the acknowledgements from the Boost page:
Those give some additional references/uses. I confess that when I decided to support interleaved bases and (other) members, I didn't know about these specific examples. I just knew about the problem and that there were use cases (I've mentioned this a few times, at least as early as a 1998 C++ Report article of mine), and I knew that unifying inheritance syntax (so that base classes weren't declared in a separate base class list and weren't initialized in a separate member initializer list) would naturally allow interleaving them with other members, that that was a semantically powerful generalization (not just a syntactic convenience), and that supporting the interleaving was likely a small use case but one worth supporting from the outset as soon as I added inheritance (in particular, it directly hits initialization safety, so even though it's a rarer need, it's a safety-important one). Sorry for the long sentences and parentheticals, I have time to write but not time to edit. 😉 Obligatory Pascal (the person) quote reference here |
|
Thanks for the explanation! |
…se`, closes hsutter#334 Disambiguates two such members having the same type Move the existing `String` wrapper into `cpp2util.h` where it can be used outside the compiler too, in this case by `store_as_base`
Direct inheritance from the same type
cpp2::store_as_base<T>multiple times is ill-formed. I suggest its API follows https://www.boost.org/doc/libs/release/libs/utility/doc/html/utility/utilities/base_from_member.html.Minimal reproducer:
Commands:
cppfront x.cpp2 clang++17 -std=c++2b -I $CPPFRONT_INCLUDE_DIR x.cppExpected result: A well-formed program.
Actual result and error:
Generated C++1
The text was updated successfully, but these errors were encountered: