RFC: Mixin, Inner, and Stateless Classes v0.5

276 views
Skip to first unread message

Nicol Bolas

unread,
Oct 29, 2015, 2:04:46 PM10/29/15
to ISO C++ Standard - Future Proposals
A while back, we had the semi-annual "let's put properties in C++ discussion". Unlike most such discussions however, that led to a more generalized idea: adding with a restrictive form of Java-style inner classes, which could be used to implement properties sanely. Several more concrete ideas were put forth along these lines, including one of my own that introduced a separate idea for stateless types.

However, that idea hit a large snag, in that inner classes have to be nested in the classes they use. So if you're trying to implement something complex like properties, you'd have to add tons of boilerplate code to make the inner class proxy work. For every property you write. That's not to say that inner classes are all about properties, but that is a use case of them.

The original inline class idea had the notion of being able to declare such constructs outside of a class, but they had some limitations. Then, I started playing around with the idea of allowing "inner classes" to be declared outside of a type, but as a template. One of the template parameters would be filled in with the actual class it is an inner class of. So the common boilerplate could go into there.

And then, I realized that I was really just solving the CRTP problem. That is, I was declaring a way to write a class that would be used by another class, injecting its definitions into the other class as if they were one type.

In short, I'd created language support for C++ mixins. Indeed, I realized that inner classes and mixins are really kinda the same thing, if you think about their effects.

So... here's a proposal that provides mixins, inner classes, and stateless classes to C++. What do you think? Is this a functional idea? What cases did I miss?
Mixins, Inner, and Stateless Classess.html
Mixins, Inner, and Stateless Classess.md

Tony V E

unread,
Oct 29, 2015, 2:31:46 PM10/29/15
to Standard Proposals
Have you looked at mixins from other languages, such as D?  (For better or worse.  ie for both what works well and what we should avoid.)
Tony

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

Nicol Bolas

unread,
Oct 29, 2015, 3:14:09 PM10/29/15
to ISO C++ Standard - Future Proposals
On Thursday, October 29, 2015 at 2:31:46 PM UTC-4, Tony V E wrote:
Have you looked at mixins from other languages, such as D?  (For better or worse.  ie for both what works well and what we should avoid.)

I didn't look at it while crafting the proposal.

Taking a quick look at D, it treats (template) mixins as a first-class construct, distinct from others. That is far more of a heavy-handed approach than I wanted to get into here. It's basically a form of safe macro expansion. What I proposed is just a class, with a few restrictions and automatic helpers on its use. C++'s multiple inheritance functionality is leveraged to do the actual injection.

D's version may be better, in that the declarations becomes truly a part of the class. But it would be a lot more complicated of a proposal than just a few adjustments to certain uses of classes.

Klaim - Joël Lamotte

unread,
Oct 29, 2015, 7:59:37 PM10/29/15
to std-pr...@isocpp.org
The word "mixin" means different things in different languages.
The current discussion is confusing because of this.
I think that what you want is "interface composition" which is not what D calls a mixin.


--

Matt Calabrese

unread,
Oct 29, 2015, 8:14:41 PM10/29/15
to ISO C++ Standard - Future Proposals
On Thu, Oct 29, 2015 at 11:04 AM, Nicol Bolas <jmck...@gmail.com> wrote:
And then, I realized that I was really just solving the CRTP problem. That is, I was declaring a way to write a class that would be used by another class, injecting its definitions into the other class as if they were one type.

In short, I'd created language support for C++ mixins. Indeed, I realized that inner classes and mixins are really kinda the same thing, if you think about their effects.

So... here's a proposal that provides mixins, inner classes, and stateless classes to C++. What do you think? Is this a functional idea? What cases did I miss?

I'm just starting to skim this, but it would help a lot if this started off with motivating cases that lead to the desire for such facilities. It sort of jumps right into definitions and implementation without first explaining what issues the proposal helps with. Benefits of mixins in some form might seem obvious to some, but it should probably be a little more formally presented up top.

Matt Calabrese

unread,
Oct 29, 2015, 8:36:44 PM10/29/15
to ISO C++ Standard - Future Proposals
On Thu, Oct 29, 2015 at 11:04 AM, Nicol Bolas <jmck...@gmail.com> wrote:
So... here's a proposal that provides mixins, inner classes, and stateless classes to C++. What do you think? Is this a functional idea? What cases did I miss?

The analysis accompanying the example of CRTP composition that is provided is a bit misleading. You can compose such constructs with CRTP fairly easily in practice and the metaphor comparing it to pure virtual functions doesn't even break down -- all you do is you pass in the derived type in the middle base as opposed to middle base's instantiation. In other words, in your example, you'd do ": public A<derived>" rather than ": public A<B<derived>>" if the base needs to depend on facilities provided in derived. Maybe there is some other kind of point you are trying to make with the code example there, but it's not immediately clear to me. This kind of composition is not too uncommon with CRTP.

Nicol Bolas

unread,
Oct 29, 2015, 8:45:52 PM10/29/15
to ISO C++ Standard - Future Proposals


On Thursday, October 29, 2015 at 8:36:44 PM UTC-4, Matt Calabrese wrote:
On Thu, Oct 29, 2015 at 11:04 AM, Nicol Bolas <jmck...@gmail.com> wrote:
So... here's a proposal that provides mixins, inner classes, and stateless classes to C++. What do you think? Is this a functional idea? What cases did I miss?

The analysis accompanying the example of CRTP composition that is provided is a bit misleading. You can compose such constructs with CRTP fairly easily in practice and the metaphor comparing it to pure virtual functions doesn't even break down -- all you do is you pass in the derived type in the middle base as opposed to middle base's instantiation. In other words, in your example, you'd do ": public A<derived>" rather than ": public A<B<derived>>" if the base needs to depend on facilities provided in derived.

And what if you want half in half? That is, if B should provide some of the facilities that A requires, while `derived` provides the rest?

As a more concrete case, let's say that mixin `A` requires that the derived class implement `foo` and `bar`. Now `B` uses the mixin, and it implements `bar`, while requiring that it's user implement `blah`. Therefore, the combined mixin `B` requires `foo` and `blah`. So `derived` implements `foo` and `blah`.

That can't happen with the CRTP. One class must implement the full requirements. While it may be `derived` rather than `B`, there is no chance for one to implement some and one to implement the other.

Matt Calabrese

unread,
Oct 29, 2015, 8:47:40 PM10/29/15
to ISO C++ Standard - Future Proposals
Just some advice -- I wouldn't depend on soft keywords as you are. Unless I'm misremembering, at Kona it ultimately wasn't even presented by Gor and I get the sense that there is little chance it would be accepted.

Nicol Bolas

unread,
Oct 29, 2015, 8:50:27 PM10/29/15
to ISO C++ Standard - Future Proposals
On Thursday, October 29, 2015 at 7:59:37 PM UTC-4, Klaim - Joël Lamotte wrote:
The word "mixin" means different things in different languages.
The current discussion is confusing because of this.
I think that what you want is "interface composition" which is not what D calls a mixin.

What I have called a mixin in this paper is an accurate representation of C++ uses of that term. Googling "C++ mixin" reveals the term "mixin" being used for both the reverse-inheritance version and the CRTP-based version. There are even several Stack Overflow C++ questions that use the term "mixin" to mean either of these implementations.

My use of terminology is correct within the bounds of C++. That's why I went through a long spiel of explaining exactly what the term means (for the purposes of the proposal) at the start. I do not intend for this feature to match any particular thing in any other language.

Matt Calabrese

unread,
Oct 29, 2015, 8:55:46 PM10/29/15
to ISO C++ Standard - Future Proposals
On Thu, Oct 29, 2015 at 5:45 PM, Nicol Bolas <jmck...@gmail.com> wrote:


On Thursday, October 29, 2015 at 8:36:44 PM UTC-4, Matt Calabrese wrote:
On Thu, Oct 29, 2015 at 11:04 AM, Nicol Bolas <jmck...@gmail.com> wrote:
So... here's a proposal that provides mixins, inner classes, and stateless classes to C++. What do you think? Is this a functional idea? What cases did I miss?

The analysis accompanying the example of CRTP composition that is provided is a bit misleading. You can compose such constructs with CRTP fairly easily in practice and the metaphor comparing it to pure virtual functions doesn't even break down -- all you do is you pass in the derived type in the middle base as opposed to middle base's instantiation. In other words, in your example, you'd do ": public A<derived>" rather than ": public A<B<derived>>" if the base needs to depend on facilities provided in derived.

And what if you want half in half? That is, if B should provide some of the facilities that A requires, while `derived` provides the rest?

That still works. "derived" publically inherits from "B," so whatever "B" provides is there in "derived", too. This is not an uncommon usage of CRTP in existing C++.
 
On Thu, Oct 29, 2015 at 5:45 PM, Nicol Bolas <jmck...@gmail.com> wrote:
That can't happen with the CRTP. One class must implement the full requirements. While it may be `derived` rather than `B`, there is no chance for one to implement some and one to implement the other.

That's not true. This is a common pattern with CRTP. The intermediate base can provide some definitions and a further child can provide the rest. When you need this kind of composition of CRTP bases, you just always pass the furthest required child through each CRTP base. Maybe we're talking about different problems here, but I don't think so.

Nicol Bolas

unread,
Oct 29, 2015, 9:07:20 PM10/29/15
to ISO C++ Standard - Future Proposals
On Thursday, October 29, 2015 at 8:55:46 PM UTC-4, Matt Calabrese wrote:
On Thu, Oct 29, 2015 at 5:45 PM, Nicol Bolas <jmck...@gmail.com> wrote:
On Thursday, October 29, 2015 at 8:36:44 PM UTC-4, Matt Calabrese wrote:
On Thu, Oct 29, 2015 at 11:04 AM, Nicol Bolas <jmck...@gmail.com> wrote:
So... here's a proposal that provides mixins, inner classes, and stateless classes to C++. What do you think? Is this a functional idea? What cases did I miss?

The analysis accompanying the example of CRTP composition that is provided is a bit misleading. You can compose such constructs with CRTP fairly easily in practice and the metaphor comparing it to pure virtual functions doesn't even break down -- all you do is you pass in the derived type in the middle base as opposed to middle base's instantiation. In other words, in your example, you'd do ": public A<derived>" rather than ": public A<B<derived>>" if the base needs to depend on facilities provided in derived.

And what if you want half in half? That is, if B should provide some of the facilities that A requires, while `derived` provides the rest?

That still works. "derived" publically inherits from "B," so whatever "B" provides is there in "derived", too. This is not an uncommon usage of CRTP in existing C++.

I hadn't realized that. Fair enough.


On Thursday, October 29, 2015 at 8:47:40 PM UTC-4, Matt Calabrese wrote:
Just some advice -- I wouldn't depend on soft keywords as you are. Unless I'm misremembering, at Kona it ultimately wasn't even presented by Gor and I get the sense that there is little chance it would be accepted.

It's not dependent on soft keywords. They're just the easiest way to avoid the generally pointless questions of "how do you specify it" rather than the more fruitful questions of "do we want this and what behavior should it have?" Much like P0057 uses <await-key-word> and so forth as placeholders for the actual syntax.

Nicol Bolas

unread,
Oct 30, 2015, 12:40:17 PM10/30/15
to ISO C++ Standard - Future Proposals
On Thursday, October 29, 2015 at 9:07:20 PM UTC-4, Nicol Bolas wrote:
On Thursday, October 29, 2015 at 8:55:46 PM UTC-4, Matt Calabrese wrote:
On Thu, Oct 29, 2015 at 5:45 PM, Nicol Bolas <jmck...@gmail.com> wrote:
On Thursday, October 29, 2015 at 8:36:44 PM UTC-4, Matt Calabrese wrote:
On Thu, Oct 29, 2015 at 11:04 AM, Nicol Bolas <jmck...@gmail.com> wrote:
So... here's a proposal that provides mixins, inner classes, and stateless classes to C++. What do you think? Is this a functional idea? What cases did I miss?

The analysis accompanying the example of CRTP composition that is provided is a bit misleading. You can compose such constructs with CRTP fairly easily in practice and the metaphor comparing it to pure virtual functions doesn't even break down -- all you do is you pass in the derived type in the middle base as opposed to middle base's instantiation. In other words, in your example, you'd do ": public A<derived>" rather than ": public A<B<derived>>" if the base needs to depend on facilities provided in derived.

And what if you want half in half? That is, if B should provide some of the facilities that A requires, while `derived` provides the rest?

That still works. "derived" publically inherits from "B," so whatever "B" provides is there in "derived", too. This is not an uncommon usage of CRTP in existing C++.

I hadn't realized that. Fair enough.

Thinking about it more, this raises a question about how such a language feature should work.

As it stands, when using the pure CRTP method, each mixin in a composition has to forward the derived class through to its mixin bases. In the above code, the `derived` class has ultimate priority with regard to its interface. That is, if both `B` and `derived` implement the same feature that's used by `A`, then the `derived` one is the one that gets called.

Is this the behavior we would actually want, though? The current behavior is used if for no other reason than that it's the only way to make it actually work. Whereas if the feature is a first-class language feature, we could implement it either way.

On the one hand, the derived-first behavior mirrors that of a virtual function: the most derived class has ultimate priority over the interface.

On the other hand, the general idea here is the inversion of the usual control relationship. As such, the least derived class should have ultimate priority. And if you think about it, it kind of has to. After all, if `A` tries to call a method that `A` itself implements, it ought to always call `A`'s version, regardless of what `derived` does.

As a first-class language feature, there is no explicit `self()` method to call. So the user does not decide when things propagate up the inheritance chain. The compiler must decide, for each name lookup, if you meant something in this class or something in one of the derived classes.

With the current CRTP-based system, the rule would have to be "check my class, then jump to the most derived class, then to his parents, etc." The fully inverted way would be "check my class, then my mixin parent, etc."

I liked the simplicity of the fully inverted method. I just don't know if it is the right way to do it, the way users would expect inverted relationships to work.

Then again, your example does seem to raise an interesting issue of scope. Consider these mixins, implemented the current way:

template<typename derived>
struct A
{
 
//CRTP stuff
};

template<typename derived>
struct B : public A<B<derived>>
{
 
//CRTP stuff
};

template<typename derived>
struct C : public A<derived>
{
 
//CRTP stuff
};

In this example, `B` and `C` represent two distinct and useful uses of mixins.

`B` is declaring itself to be a mixin. But it just so happens that some of its functionality is implemented via another mixin. This is not something `B` wants to expose to its users, so `B` explicitly isolates its users from `A`. Therefore, `A`'s reach is restricted to `B`.

`C` is declaring itself to be a mixin that is composed of itself and another mixin. `A` is being allowed to access whoever it is that `C` is mixed into.

One is "implemented with;" the other is "mixin composition." My current proposal has no equivalent to this. It uses public/private inheritance to decide when the reach ends, but that's obviously too heavy handed (`A` would be unable to augment `B`'s public interface).

I'm going to have to come up with a solution for this, as it seems like an incredibly useful distinction to be able to make.

Andrew Tomazos

unread,
Oct 30, 2015, 10:47:22 PM10/30/15
to std-pr...@isocpp.org
This proposal is too long to have an inadequate summary/abstract.

I would advise to replace the text "Two of these features are really two halves of the same conceptual coin (though they are separate features). The third feature is an optimization for certain use cases that make the other two features much more attractive."

... with ...

"The first is <X>. <X> is .... *one or two sentences describing X*.  The second is <Y>.  <Y> is... *one or two sentences describing Y*.  The third is <Z>.  <Z> is... *one or two sentences describing Z*."

Where X, Y and Z might be "Mixin Class", "Inner Class" and "Stateless Class" - for example - if those are the three features you allude to in the opening sentence.


--

Nicol Bolas

unread,
Oct 31, 2015, 9:05:32 AM10/31/15
to ISO C++ Standard - Future Proposals
On Friday, October 30, 2015 at 10:47:22 PM UTC-4, Andrew Tomazos wrote:
This proposal is too long to have an inadequate summary/abstract.

I would advise to replace the text "Two of these features are really two halves of the same conceptual coin (though they are separate features). The third feature is an optimization for certain use cases that make the other two features much more attractive."

... with ...

"The first is <X>. <X> is .... *one or two sentences describing X*.  The second is <Y>.  <Y> is... *one or two sentences describing Y*.  The third is <Z>.  <Z> is... *one or two sentences describing Z*."

Where X, Y and Z might be "Mixin Class", "Inner Class" and "Stateless Class" - for example - if those are the three features you allude to in the opening sentence.

That's a good point. The reason I hold off on talking about what's actually in it is because it looks like 3 separate features that have nothing to do with one another. So I thought my first goal should be to explain how they're related and how each one complements the other.

That probably made more sense when it was only a 20KB document instead of a 60KB one ;)

Nicol Bolas

unread,
Nov 3, 2015, 4:39:22 PM11/3/15
to ISO C++ Standard - Future Proposals
Here's an improved version of the proposal. Changelist:

    * Altered intro and restructured the document, putting uses after concepts.
    * Removed erroneous claims about current CRTP implementations.
    * Added functionality for explicitly restricting the reach of a mixin.
    * Added discussion of mixin overriding inversion.
    * Added section on alternative designs in other languages.
    * Subsection on how inner class offsets are generated.
    * Added section on changes.
Mixins, Inner, and Stateless Classess.md

Matthew Woehlke

unread,
Nov 16, 2015, 3:11:50 PM11/16/15
to std-pr...@isocpp.org
On 2015-10-29 14:04, Nicol Bolas wrote:
> So... here's a proposal that provides mixins, inner classes, and stateless
> classes to C++. What do you think? Is this a functional idea? What cases
> did I miss?

Sorry for jumping in so late... I'm still hoping to go back and re-read
the original proposal to compare notes. Meanwhile, finally read the
proposal. Comments follow:

> Let's say that you have some container class C. It has an interface
> that works for you and your needs. But with the ranges proposal, you
> know that it doesn't really fit into that paradigm. It is
> conceptually a range, but it doesn't actually fit the range paradigm.
> And you don't want to rewrite your interface; if it's not broken,
> don't fix it.
>
> The way to resolve that today would be to create some proxy object
> PC, which internally stores a pointer/reference to a C instance. This
> object would translate the interface of C into one appropriate for
> the ranges proposal.

Do you mean like
http://permalink.gmane.org/gmane.comp.lib.qt.devel/21327 (see
qtEnumerate)? Or http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1104? :-)
Those sound like potential interesting use cases (if you happen to be
looking for concrete, real-world examples).

This brings up a related point; we'll want lifetime extension for inner
classes (i.e. retaining an inner class extends the life of a temporary
outer class that contains it).

IOW, I want to be able to do this:

Outer foo();
auto& i = foo().inner;
// ...do stuff with i

Or, equivalently, but more particularly:

for (auto i : foo().inner)
// ...

Hopefully though we'll be getting the general form of this and it can be
a moot point :-).

> In C++ as it currently stands, every object needs to have a memory
> location. And two unrelated types cannot have the same memory
> location.

Pedantic: I believe a struct and a member thereof can already have the
same address? The restriction applies to objects at the same scope.
Therefore, here:

> Stateless types effectively have to be able to break this rule. The
> memory location of a stateless member subobject can be the same
> location as the object it is a member of. And two sibling members of
> the same type may have the same location if one of them is
> stateless.

The first statement is already the case. Just the second one is new.

Is it worth talking about trivially copyability here? (Specifically,
stateless zero-sized classes should not affect trivial copyability.) Or
do you consider this sufficiently "obvious"?

> - Types that declare stateful inner class members cannot have a
> trivial default constructor, and therefore cannot be trivial types.
>
> - Stateful inner class members prevent their owning types from being
> standard layout.

There is some phrasing inversion going on here. I might consolidate
these as the first point: "...nor can such types be standard layout" (or
even just "...nor standard layout"). Or rephrase the first "Stateful
inner class members prevent their owning types from having a trivial
default constructor...".

> for each stateful inner class member, the compiler must have access
> to some data (typically a byte offset) which is used to convert this
> from Outer::Inner* to Outer*.

Question: is this necessary if a) there is exactly one NSDM of the
stateful inner class type, and b) no additional members of that type may
be added (e.g. by a derived class)?

I want to say "no", in which case we could theoretically allow these to
use a static offset also. *If* such an optimization is worthwhile, it
implies preventing additional NSDM's of the inner class type being
created. A private type would accomplish this, but I think also means
that no public member could use the type... so maybe it would be
interesting to allow e.g. "final" inner class types?

Just throwing it out there. I'm fine passing on it if it seems too
convoluted.

> Mixin Classes
> [...syntax...]

Is there a strong reason why a mixin can't just be an implicit template?
I.e.:

std::mixin class Foo { ... };
class Bar : public Foo { ... };

(This might require something like std::mixin_user to access the
typename of the final class explicitly, but that's easy.)

In case of additional template parameters, this would look like:

template <int N> std::mixin class Foo { ... };
class Bar : public Foo<3> { ... };

Naming a mixin (externally) could be done like:

typedef std::mixin<Bar> Foo<3> BarMixinFoo3;

Templated aliases would be conditionally legal:

template <int K>
using std::mixin<Bar> Foo<K>; // error

template <typename T>
using std::mixin<T> Foo<3>; // okay

template <int K> class Dog;
template <int K>
using std::mixin<Dog<K>> Foo<K>; // ???

The first is an error; the non-template-type Bar cannot have a templated
mixin. The second is always okay. The third is probably also legal, as a
declaration is not sufficient to know that Dog<K> always has mixin
Foo<K>. (Even the definition is insufficient, as specialization could
break the relation.) I believe you give a similar restriction? (I
honestly don't entirely follow that section.)

> No variables of mixin types can be declared

Just concrete instances? Or would this include pointers/references? I
believe the former is intended, but perhaps this could be worded to make
that more clear.

--
Matthew

Nicol Bolas

unread,
Nov 16, 2015, 5:24:42 PM11/16/15
to ISO C++ Standard - Future Proposals, mwoehlk...@gmail.com

A member that is of an inner class type is still a non-static data member. And they behave exactly like any NSDM, except where explicitly stated. So if `foo().inner` would extend the lifetime if `inner` were an `int`, then it would still extend the lifetime if `inner` were an inner class member.
 
> In C++ as it currently stands, every object needs to have a memory
> location. And two unrelated types cannot have the same memory
> location.

Pedantic: I believe a struct and a member thereof can already have the
same address? The restriction applies to objects at the same scope.
Therefore, here:

> Stateless types effectively have to be able to break this rule. The
> memory location of a stateless member subobject can be the same
> location as the object it is a member of. And two sibling members of
> the same type may have the same location if one of them is
> stateless.

The first statement is already the case. Just the second one is new.

Is it worth talking about trivially copyability here? (Specifically,
stateless zero-sized classes should not affect trivial copyability.) Or
do you consider this sufficiently "obvious"?

Well, stateless classes can still affect trivial copyability just like any other type. If you implement the copy constructor on them, then they are no longer trivially copyable.

My point is that being declared as stateless has no effects on trivial copyability one way or another. The rules work the same as they did before.

> for each stateful inner class member, the compiler must have access
> to some data (typically a byte offset) which is used to convert this
> from Outer::Inner* to Outer*.

Question: is this necessary if a) there is exactly one NSDM of the
stateful inner class type, and b) no additional members of that type may
be added (e.g. by a derived class)?

I want to say "no", in which case we could theoretically allow these to
use a static offset also. *If* such an optimization is worthwhile, it
implies preventing additional NSDM's of the inner class type being
created. A private type would accomplish this, but I think also means
that no public member could use the type... so maybe it would be
interesting to allow e.g. "final" inner class types?

Just throwing it out there. I'm fine passing on it if it seems too
convoluted.

> Mixin Classes
> [...syntax...]

Is there a strong reason why a mixin can't just be an implicit template?

I cordially dislike implicit templates. Also, with an explicit template, it becomes much easier syntactically to create a contextual keyword.

How would you apply a concept restriction to an implicit template? How would you name the class being mixed into at all?

Also, you may be looking at the old version of the proposal. The mixin part in particular has been upgraded since then; my later post contains the updated version.

Matthew Woehlke

unread,
Nov 17, 2015, 10:30:34 AM11/17/15
to std-pr...@isocpp.org
On 2015-11-16 17:24, Nicol Bolas wrote:
> On Monday, November 16, 2015 at 3:11:50 PM UTC-5, Matthew Woehlke wrote:
>> We'll want lifetime extension for inner classes (i.e. retaining an
>> inner class extends the life of a temporary outer class that
>> contains it).
>>
>> IOW, I want to be able to do this:
>>
>> Outer foo();
>> auto& i = foo().inner;
>> // ...do stuff with i
>>
>> Or, equivalently, but more particularly:
>>
>> for (auto i : foo().inner)
>> // ...
>
> A member that is of an inner class type is still a non-static data member.
> And they behave exactly like any NSDM, except where explicitly stated. So
> if `foo().inner` would extend the lifetime if `inner` were an `int`, then
> it would still extend the lifetime if `inner` were an inner class member.

Ack, true, true... let me rephrase that:

Foo::Inner& bar(Foo&);
auto& i = bar(foo());
// ...do stuff with i

I *want* to say this should work. However, I'm now thinking it would be
better addressed by the lifetime extension proposal. And per above,
hopefully the inner class proposal doesn't need to say anything about it
specifically as it would be handled under the same rules as any member
(per above).

>> On 2015-10-29 14:04, Nicol Bolas wrote:
>>> In C++ as it currently stands, every object needs to have a memory
>>> location. And two unrelated types cannot have the same memory
>>> location.
>>>
>>> Stateless types effectively have to be able to break this rule. The
>>> memory location of a stateless member subobject can be the same
>>> location as the object it is a member of. And two sibling members of
>>> the same type may have the same location if one of them is
>>> stateless.
>>
>> Is it worth talking about trivially copyability here? (Specifically,
>> stateless zero-sized classes should not affect trivial copyability.) Or
>> do you consider this sufficiently "obvious"?
>
> My point is that being declared as stateless has no effects on trivial
> copyability one way or another. The rules work the same as they did before.

Right; I agree with the statements made in the proposal. I'm only
mentioning, as a point for consideration, if *this specific spot* would
benefit from a brief mention of that (even just a reference to see some
other part of the proposal). That's all.

On further consideration... maybe not. It *is* covered later, after all,
and I'm less convinced that a mention here would actually be beneficial.
(I'll blame this partly on having written comments as I was reading
through.)

>>> Mixin Classes
>>> [...syntax...]
>>
>> Is there a strong reason why a mixin can't just be an implicit template?
>
> I cordially dislike implicit templates. Also, with an explicit template, it
> becomes much easier syntactically to create a contextual keyword.

Fair enough. Anyway, this is syntax, which isn't set in stone yet.

> How would you apply a concept restriction to an implicit template?

Hmm, that's a fair question.

> How would you name the class being mixed into at all?

(e.g.) mixin_parent.

> Also, you may be looking at the old version of the proposal. The mixin part
> in particular has been upgraded since then; my later post contains the
> updated version.

I did read both (at least, I skimmed the changes), but I also did
originally write comments against the old version.

Just to be clear, I like the proposal overall. Thanks again!

--
Matthew

Reply all
Reply to author
Forward
0 new messages