Discussion:
Relaxing constraints on base class for aggregate types
(too old to reply)
c***@cea.fr
2013-12-15 13:34:34 UTC
Permalink
Hello,

I have encountered a situation where the wording for [dcl.init.aggr] seems
too restrictive, and I was wondering if it would be possible to change it.
Maybe this concept already exists in the norm, but let's define an "empty"
class as a trivial class having no member variable, no (virtual?) member
functions and no non-empty base class.
I suggest that aggregates can have base classes provided that they are
empty.

Here is a dumb example:

struct test1 {
int i, j;
};

struct base {
// could contain static variables & functions, typedefs (and non-virtual member functions?)
// but no non-trivial constructor or member variables
};

struct test2 : base {
int i, j;
};

int main() {
test1 t1{0,1}; // ok in C++11
test2 t2{0,1}; // not ok in C++11
return 0;
}


The point is that I often use empty base classes as a way to factorize
code. For example, if I want to assign a given ID to a class:

template<int N>
struct struct_id {
static const int ID = N;
};

struct test : struct_id<5> {
int i, j;
};


In the example above, the "test" struct should still be an aggregate, but
the current wording prevents it.

One way out is to explicitly write the constructor:

struct test2 : base {
test2() = default; // needed for default initialization
test2(int i_, int j_) : i(i_), j(j_) {}
int i, j;
};


But this is wrong for obvious reasons. Even if trivial:

1. it is tedious to write if the class has many data members, and also
implies the declaration of a default constructor,
2. it is tedious to maintain, as adding a new data member also implies
modifying the constructor,
3. it is error prone, as one could easily do the initialization wrong
(by missing a variable for example).

I could not find any proposal that would already address this issue. Does
this seem reasonable to you?
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2013-12-15 13:51:34 UTC
Permalink
it is tedious to write if the class has many data members, and also implies
the declaration of a default constructor,
it is tedious to maintain, as adding a new data member also implies
modifying the constructor,
it is error prone, as one could easily do the initialization wrong (by
missing a variable for example).
I could not find any proposal that would already address this issue. Does
this seem reasonable to you?
I wouldn't mind being able to do it, but perhaps it's targeting a rather narrow
case. You can make sure that you don't miss initializations by using non-static
data member initializers, which are now allowed for aggregates.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2013-12-15 22:36:25 UTC
Permalink
Post by Ville Voutilainen
it is tedious to write if the class has many data members, and also implies
the declaration of a default constructor,
it is tedious to maintain, as adding a new data member also implies
modifying the constructor,
it is error prone, as one could easily do the initialization wrong (by
missing a variable for example).
I could not find any proposal that would already address this issue. Does
this seem reasonable to you?
I wouldn't mind being able to do it, but perhaps it's targeting a rather narrow
case. You can make sure that you don't miss initializations by using non-static
data member initializers, which are now allowed for aggregates.
I think he's referring to duplicating the aggregate initialization
semantics, which at a minimum demands declaration of a constructor with
a parameter for each nonstatic data member.

Aggregate initialization allows omission of trailing members though, so
each constructor parameter should get a default argument of {}.

However, this idiom is imperfect because copy-list-initialization from
an empty list requires a non-explicit default constructor:

1. Each parameter must have a non-explicit default constructor to be
used with {}, or else you have to manually write = member_type(), which
is copy initialization and relies on copy elision. So the requirement is
either implicit default constructible or move constructible.

2. If the would-be aggregate constructor is implicit, it will perform
conversion unlike aggregate semantics. If it is explicit, it will not
work with copy-list-initialization. Implicit constructors for N != 1
arguments and explicit for N == 1 provides the best fidelity, but you
cannot emulate an aggregate and initialize from a one-element
braced-init-list without allowing implicit conversion.

Aggregate semantics are very nice so it would be a plus to support
migration from an aggregate to some constructor idiom without any
knock-on effects.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2013-12-15 14:18:43 UTC
Permalink
Post by c***@cea.fr
Hello,
I have encountered a situation where the wording for [dcl.init.aggr] seems
too restrictive, and I was wondering if it would be possible to change it.
Maybe this concept already exists in the norm, but let's define an "empty"
class as a trivial class having no member variable, no (virtual?) member
functions and no non-empty base class.
I suggest that aggregates can have base classes provided that they are
empty.
The concept of an empty class already exists as part of the
specification of the standard layout property, where they are allowed as
bases.

It's also available as the type trait std::is_empty which is true for
conditions similar to what you mention:

T is a class type, but not a union type, with no non-static data members
other than bit-fields of length 0, no virtual member functions, no
virtual base classes, and no base class B for which is_empty<B>::value
is false.

C++ International Standard I think that allowing such bases for
aggregates would be wonderful. I seem to recall being annoyed by the
restriction in the past. Standard layout was introduced in C++11 so the
empty base semantic perhaps has yet to integrate fully into the language.

Also, perhaps empty bases should be allowed for unions. The idea just
occurred to me; I haven't really considered this.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2013-12-15 14:51:50 UTC
Permalink
Post by c***@cea.fr
Hello,
I have encountered a situation where the wording for [dcl.init.aggr] seems
too restrictive, and I was wondering if it would be possible to change it.
Maybe this concept already exists in the norm, but let's define an "empty"
class as a trivial class having no member variable, no (virtual?) member
functions and no non-empty base class.
I suggest that aggregates can have base classes provided that they are
empty.
The concept of an empty class already exists as part of the specification of
the standard layout property, where they are allowed as bases.
It's also available as the type trait std::is_empty which is true for
T is a class type, but not a union type, with no non-static data members
other than bit-fields of length 0, no virtual member functions, no virtual
base classes, and no base class B for which is_empty<B>::value is false.
I think that allowing such bases for aggregates would be wonderful. I seem
to recall being annoyed by the restriction in the past. Standard layout was
introduced in C++11 so the empty base semantic perhaps has yet to integrate
fully into the language.
Also, perhaps empty bases should be allowed for unions. The idea just
occurred to me; I haven't really considered this.
I wouldn't fnd the following far-fetched:

struct B
{
int i;
int j;
};

struct D : B
{
};

D d{1,2};

Now, 'morally', D didn't really do anything that would make the combination
of D and B a non-aggregate. D could've held B as a member subobject(*)
and it would be able to aggegate-initialize the combination. It seems to me
we're treating base subobjects non-uniformally here.

(*) This is fine:

struct B
{
int i;
int j;
};
struct D
{
B b;
};
D d{1,2};

Alternatively, having an empty B as a data member works fine, the combination
is still an aggregate:

struct B {};
struct D
{
int i;
int j;
B b;
};
D d{1,2};
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
c***@cea.fr
2013-12-15 22:31:09 UTC
Permalink
Post by c***@cea.fr
Post by c***@cea.fr
Hello,
I have encountered a situation where the wording for [dcl.init.aggr]
seems
Post by c***@cea.fr
too restrictive, and I was wondering if it would be possible to change
it.
Post by c***@cea.fr
Maybe this concept already exists in the norm, but let's define an
"empty"
Post by c***@cea.fr
class as a trivial class having no member variable, no (virtual?) member
functions and no non-empty base class.
I suggest that aggregates can have base classes provided that they are
empty.
The concept of an empty class already exists as part of the
specification of
Post by c***@cea.fr
the standard layout property, where they are allowed as bases.
It's also available as the type trait std::is_empty which is true for
T is a class type, but not a union type, with no non-static data members
other than bit-fields of length 0, no virtual member functions, no
virtual
Post by c***@cea.fr
base classes, and no base class B for which is_empty<B>::value is false.
I think that allowing such bases for aggregates would be wonderful. I
seem
Post by c***@cea.fr
to recall being annoyed by the restriction in the past. Standard layout
was
Post by c***@cea.fr
introduced in C++11 so the empty base semantic perhaps has yet to
integrate
Post by c***@cea.fr
fully into the language.
Also, perhaps empty bases should be allowed for unions. The idea just
occurred to me; I haven't really considered this.
struct B
{
int i;
int j;
};
struct D : B
{
};
D d{1,2};
Now, 'morally', D didn't really do anything that would make the combination
of D and B a non-aggregate. D could've held B as a member subobject(*)
and it would be able to aggegate-initialize the combination. It seems to me
we're treating base subobjects non-uniformally here.
struct B
{
int i;
int j;
};
struct D
{
B b;
};
D d{1,2};
Alternatively, having an empty B as a data member works fine, the combination
struct B {};
struct D
{
int i;
int j;
B b;
};
D d{1,2};
So in other words, you actually suggest to go further and replace the "has
no base class" requirement by "either has no non-static data members in the
most derived class and at most one base class with non-static data members,
or has no base classes with non-static data members" (borrowed from
[class]/6, defining standard layout classes). I agree that is a more
uniform hence superior solution. Thank you David Krauss for pointing out
std::is_empty and standard layout classes, it is indeed very similar.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2013-12-15 22:59:31 UTC
Permalink
Post by c***@cea.fr
Post by Ville Voutilainen
Post by c***@cea.fr
Hello,
I have encountered a situation where the wording for [dcl.init.aggr] seems
too restrictive, and I was wondering if it would be possible to change it.
Maybe this concept already exists in the norm, but let's define an "empty"
class as a trivial class having no member variable, no (virtual?) member
functions and no non-empty base class.
I suggest that aggregates can have base classes provided that they are
empty.
The concept of an empty class already exists as part of the
specification of
the standard layout property, where they are allowed as bases.
It's also available as the type trait std::is_empty which is true for
T is a class type, but not a union type, with no non-static data members
other than bit-fields of length 0, no virtual member functions, no virtual
base classes, and no base class B for which is_empty<B>::value is false.
I think that allowing such bases for aggregates would be wonderful. I seem
to recall being annoyed by the restriction in the past. Standard layout was
introduced in C++11 so the empty base semantic perhaps has yet to integrate
fully into the language.
Also, perhaps empty bases should be allowed for unions. The idea just
occurred to me; I haven't really considered this.
struct B
{
int i;
int j;
};
struct D : B
{
};
D d{1,2};
Now, 'morally', D didn't really do anything that would make the combination
of D and B a non-aggregate. D could've held B as a member subobject(*)
and it would be able to aggegate-initialize the combination. It seems to me
we're treating base subobjects non-uniformally here.
struct B
{
int i;
int j;
};
struct D
{
B b;
};
D d{1,2};
Alternatively, having an empty B as a data member works fine, the combination
struct B {};
struct D
{
int i;
int j;
B b;
};
D d{1,2};
So in other words, you actually suggest to go further and replace the "has
no base class" requirement by "either has no non-static data members in the
most derived class and at most one base class with non-static data members,
or has no base classes with non-static data members" (borrowed from
[class]/6, defining standard layout classes). I agree that is a more uniform
hence superior solution. Thank you David Krauss for pointing out
std::is_empty and standard layout classes, it is indeed very similar.
To clarify: I would strive for allowing aggregate initialization of
anything that is
standard-layout and accessible, including

struct B
{
protected:
int i;
int j;
};

struct D : B
{
D() : B{1, 2} {} // sure, why not?
};

struct B
{
friend class D;
private:
int i;
int j;
};

struct D : B
{
D() : B{1, 2} {} // sure, why not?
};

Even further, I don't see why we should necessarily stop there; the restriction
that aggregates or standard-layout types can't have virtual functions leads to
a situation where aggregate initialization can't be used for a type that has
virtual functions. That seems overly restrictive to me. Aggregate initialization
runs arbitrarily complex code for aggregates that have non-trivial members
or NSDMIs, I find it hard to reason why it couldn't initialize a virtual table.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2013-12-15 23:12:59 UTC
Permalink
Post by Ville Voutilainen
Even further, I don't see why we should necessarily stop there; the
restriction that aggregates or standard-layout types can't have
virtual functions leads to a situation where aggregate initialization
can't be used for a type that has virtual functions. That seems overly
restrictive to me. Aggregate initialization runs arbitrarily complex
code for aggregates that have non-trivial members or NSDMIs, I find it
hard to reason why it couldn't initialize a virtual table.
For that matter, access protected NSDMs with initializers could be allowed.

In C++03 aggregates were a superset of POD classes, but in C++11 they
have been divorced and aggregates are only distinguished by allowing
aggregate initialization.

Another inconsistency of aggregates vs. constructors is compatibility
with inheriting constructors. This would be exacerbated if inheriting
aggregate initialization were allowed by other means.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2013-12-15 23:59:00 UTC
Permalink
Post by David Krauss
Post by Ville Voutilainen
Even further, I don't see why we should necessarily stop there; the
restriction that aggregates or standard-layout types can't have virtual
functions leads to a situation where aggregate initialization can't be used
for a type that has virtual functions. That seems overly restrictive to me.
Aggregate initialization runs arbitrarily complex code for aggregates that
have non-trivial members or NSDMIs, I find it hard to reason why it couldn't
initialize a virtual table.
For that matter, access protected NSDMs with initializers could be allowed.
Sure, since once you have access and can aggregate-initialize, you can also
omit initializers just like current aggregates with NSDMIs allow you to do,
so that sounds very much like a natural extension.
Post by David Krauss
Another inconsistency of aggregates vs. constructors is compatibility with
inheriting constructors. This would be exacerbated if inheriting aggregate
initialization were allowed by other means.
I'm not sure I know what you mean here, got an example?
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2013-12-16 00:52:38 UTC
Permalink
Post by Ville Voutilainen
Post by David Krauss
Another inconsistency of aggregates vs. constructors is compatibility with
inheriting constructors. This would be exacerbated if inheriting aggregate
initialization were allowed by other means.
I'm not sure I know what you mean here, got an example?
template< typename basis >
struct adaptor : basis {
#if INHERIT
using basis::basis;
#endif
friend bool operator < ( adaptor const & lhs, adaptor const & rhs );
};

struct intpair { int a, b; }

adaptor< std::pair< int > > x { 1, 2 }; // OK iff INHERIT
adaptor< inpair > y { 1, 2 }; // OK per proposal iff ! INHERIT?

An adaptor or veneer will often inherit constructors. Inheriting
constructors from an aggregate is syntactically valid but has no effect,
since implicitly declared constructors are excluded. The proposal of
aggregate-initializing the base would apply if constructors were not
inherited. Does it apply if constructors are inherited?

My first thought was that the inheriting constructor declaration would
make the derived class non-aggregate. But on second thought, if no
constructors are inherited, then there are no constructor declarations,
so it remains a candidate as an aggregate.

Furthermore, inherited constructors are implicitly defined, not
user-provided, so a nontrivial inheriting constructor declaration also
does not prevent aggregate-ness. Therefore a non-empty base of an
aggregate would need to be an aggregate to exclude user-provided
constructors, which standard layout yet allows. (But that's probably the
most natural way of specifying the feature anyway.)

TL;DR: there doesn't really appear to be an interaction between
aggregate inheritance and inheriting constructors.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2013-12-16 01:02:34 UTC
Permalink
Post by David Krauss
Post by Ville Voutilainen
Post by David Krauss
Another inconsistency of aggregates vs. constructors is compatibility with
inheriting constructors. This would be exacerbated if inheriting aggregate
initialization were allowed by other means.
I'm not sure I know what you mean here, got an example?
template< typename basis >
struct adaptor : basis {
#if INHERIT
using basis::basis;
#endif
friend bool operator < ( adaptor const & lhs, adaptor const & rhs );
};
struct intpair { int a, b; }
adaptor< std::pair< int > > x { 1, 2 }; // OK iff INHERIT
adaptor< inpair > y { 1, 2 }; // OK per proposal iff ! INHERIT?
I would hope the latter is ok regardless of INHERIT, and does nothing
for a base aggregate or a standard-layout base that has no constructors.
Post by David Krauss
TL;DR: there doesn't really appear to be an interaction between aggregate
inheritance and inheriting constructors.
Anyway, it's good to remember inheriting constructors too, as yet another
language facility with which this idea needs to work.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
c***@cea.fr
2014-01-20 20:48:24 UTC
Permalink
Post by c***@cea.fr
Post by c***@cea.fr
Post by Ville Voutilainen
Post by c***@cea.fr
Hello,
I have encountered a situation where the wording for [dcl.init.aggr] seems
too restrictive, and I was wondering if it would be possible to
change
Post by c***@cea.fr
Post by Ville Voutilainen
Post by c***@cea.fr
it.
Maybe this concept already exists in the norm, but let's define an "empty"
class as a trivial class having no member variable, no (virtual?)
member
Post by c***@cea.fr
Post by Ville Voutilainen
Post by c***@cea.fr
functions and no non-empty base class.
I suggest that aggregates can have base classes provided that they
are
Post by c***@cea.fr
Post by Ville Voutilainen
Post by c***@cea.fr
empty.
The concept of an empty class already exists as part of the specification of
the standard layout property, where they are allowed as bases.
It's also available as the type trait std::is_empty which is true for
T is a class type, but not a union type, with no non-static data
members
Post by c***@cea.fr
Post by Ville Voutilainen
Post by c***@cea.fr
other than bit-fields of length 0, no virtual member functions, no virtual
base classes, and no base class B for which is_empty<B>::value is
false.
Post by c***@cea.fr
Post by Ville Voutilainen
Post by c***@cea.fr
I think that allowing such bases for aggregates would be wonderful. I seem
to recall being annoyed by the restriction in the past. Standard
layout
Post by c***@cea.fr
Post by Ville Voutilainen
Post by c***@cea.fr
was
introduced in C++11 so the empty base semantic perhaps has yet to integrate
fully into the language.
Also, perhaps empty bases should be allowed for unions. The idea just
occurred to me; I haven't really considered this.
struct B
{
int i;
int j;
};
struct D : B
{
};
D d{1,2};
Now, 'morally', D didn't really do anything that would make the combination
of D and B a non-aggregate. D could've held B as a member subobject(*)
and it would be able to aggegate-initialize the combination. It seems
to
Post by c***@cea.fr
Post by Ville Voutilainen
me
we're treating base subobjects non-uniformally here.
struct B
{
int i;
int j;
};
struct D
{
B b;
};
D d{1,2};
Alternatively, having an empty B as a data member works fine, the combination
struct B {};
struct D
{
int i;
int j;
B b;
};
D d{1,2};
So in other words, you actually suggest to go further and replace the
"has
Post by c***@cea.fr
no base class" requirement by "either has no non-static data members in
the
Post by c***@cea.fr
most derived class and at most one base class with non-static data
members,
Post by c***@cea.fr
or has no base classes with non-static data members" (borrowed from
[class]/6, defining standard layout classes). I agree that is a more
uniform
Post by c***@cea.fr
hence superior solution. Thank you David Krauss for pointing out
std::is_empty and standard layout classes, it is indeed very similar.
To clarify: I would strive for allowing aggregate initialization of
anything that is
standard-layout and accessible, including
struct B
{
int i;
int j;
};
struct D : B
{
D() : B{1, 2} {} // sure, why not?
};
struct B
{
friend class D;
int i;
int j;
};
struct D : B
{
D() : B{1, 2} {} // sure, why not?
};
Even further, I don't see why we should necessarily stop there; the restriction
that aggregates or standard-layout types can't have virtual functions leads to
a situation where aggregate initialization can't be used for a type that has
virtual functions. That seems overly restrictive to me. Aggregate initialization
runs arbitrarily complex code for aggregates that have non-trivial members
or NSDMIs, I find it hard to reason why it couldn't initialize a virtual table.
Coming back to this suggestion, I agree on both points: 1) members need no
be
public (but need the same access scope, as for standard layout classes),
and 2)
aggregate classes can have virtual functions.

Regarding point 1), the rule of having all members in the same access scope
(public, protected or private) is necessary in order not to end up with
confusing
situations where the number of values in an initialization list depends on
the
scope. For example, if you have a case like:

struct A {
int i;
protected:
int j;
public:
int k;
}

Friend or derived classes could be allowed to initialize A like:

A a{/*i=*/1,/*j=*/2,/*k=*/3}; // case a)

On the other hand, in any other places you would only be able to initialize
the
public members as if the protected/private members did not exist, i.e.:

A a{/*i=*/1,/*k=*/3}; // case b)

I don't know if this is desirable. An alternative would be to only allow
aggregate initialization of the "most public" members (if, of course, they
are
accessible). In the example above, both cases a) and b) would thus be
identical in the sense that they would only be able to initialize public
members
"i" and "k". One drawback I can see with this solution is that adding a
single
public member to a class that previously had only private/protected members
changes completely the allowed initialization. I'm not sure this is a good
thing
either.

Another thing that comes to my mind, things would much simpler if we were
to allow designated initializers like in C:

A a{.i=0, .k=2}; // compiles everywhere
A a{.i=0, .j=1, .k=2}; // compiles within friend or derived classes

This syntax could be allowed for any class, regardless of its inheritance
chain
and of the type of is members, as far as I can tell. I see that this has
already
been proposed here:
https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IgDFqKjKlRs/CGARpDJy9JsJ
It seems that they are only targeting aggregate types, so we might cooperate
to make things better in both worlds, since I'm sure they don't need the
current
restrictions of aggregate types and would beneficiate from relaxing these
as we
are discussing here.

As for point 2), correct me if I'm wrong, but aggregate classes are only
marked
as such to allow aggregate initialization, which is purely syntactic sugar.
Since
non static data members have to reside in a single class within the
inheritance
chain, there is no ambiguity with respect to how base classes are
initialized: if
they do not contain any data member then their initialization is trivial,
else the
initialization arguments are simply forwarded to them.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Daryle Walker
2014-01-23 01:06:03 UTC
Permalink
Post by c***@cea.fr
Another thing that comes to my mind, things would much simpler if we were
A a{.i=0, .k=2}; // compiles everywhere
A a{.i=0, .j=1, .k=2}; // compiles within friend or derived classes
This syntax could be allowed for any class, regardless of its inheritance
chain
and of the type of is members, as far as I can tell. I see that this has
already
https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IgDFqKjKlRs/CGARpDJy9JsJ
It seems that they are only targeting aggregate types, so we might cooperate
to make things better in both worlds, since I'm sure they don't need the
current
restrictions of aggregate types and would beneficiate from relaxing these
as we
are discussing here.
I'm the writer of that proposal, and I added trial prose about expanded
aggregates, based on this thread. But I'm going to undo that draft and
propose expanded aggregates separately, as doing them together showed that
the mix was a bad idea. The aggregate expansion prose mostly gets lost in
the designated initializer prose, except for the parts that stick out
badly. Both proposals will be independently based off the latest C++ draft,
and can't reference each other (yet).

Daryle W.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Daryle Walker
2014-01-23 09:15:11 UTC
Permalink
Post by Daryle Walker
Post by c***@cea.fr
Another thing that comes to my mind, things would much simpler if we were
A a{.i=0, .k=2}; // compiles everywhere
A a{.i=0, .j=1, .k=2}; // compiles within friend or derived classes
This syntax could be allowed for any class, regardless of its inheritance
chain
and of the type of is members, as far as I can tell. I see that this has
already
https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IgDFqKjKlRs/CGARpDJy9JsJ
It seems that they are only targeting aggregate types, so we might cooperate
to make things better in both worlds, since I'm sure they don't need the
current
restrictions of aggregate types and would beneficiate from relaxing these
as we
are discussing here.
I'm the writer of that proposal, and I added trial prose about expanded
aggregates, based on this thread. But I'm going to undo that draft and
propose expanded aggregates separately, as doing them together showed that
the mix was a bad idea. The aggregate expansion prose mostly gets lost in
the designated initializer prose, except for the parts that stick out
badly. Both proposals will be independently based off the latest C++ draft,
and can't reference each other (yet).
I've uploaded a draft proposal for expanded aggregates<http://htmlpreview.github.io/?https://raw.github.com/CTMacUser/multiarray-iso-proposal/master/expanded-aggregate-proposal.html>
now.

Daryle W.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
c***@cea.fr
2014-01-23 20:49:17 UTC
Permalink
Post by Daryle Walker
Post by Daryle Walker
Post by c***@cea.fr
Another thing that comes to my mind, things would much simpler if we were
A a{.i=0, .k=2}; // compiles everywhere
A a{.i=0, .j=1, .k=2}; // compiles within friend or derived classes
This syntax could be allowed for any class, regardless of its
inheritance chain
and of the type of is members, as far as I can tell. I see that this has
already
https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IgDFqKjKlRs/CGARpDJy9JsJ
It seems that they are only targeting aggregate types, so we might cooperate
to make things better in both worlds, since I'm sure they don't need the
current
restrictions of aggregate types and would beneficiate from relaxing
these as we
are discussing here.
I'm the writer of that proposal, and I added trial prose about expanded
aggregates, based on this thread. But I'm going to undo that draft and
propose expanded aggregates separately, as doing them together showed that
the mix was a bad idea. The aggregate expansion prose mostly gets lost in
the designated initializer prose, except for the parts that stick out
badly. Both proposals will be independently based off the latest C++ draft,
and can't reference each other (yet).
I've uploaded a draft proposal for expanded aggregates<http://htmlpreview.github.io/?https://raw.github.com/CTMacUser/multiarray-iso-proposal/master/expanded-aggregate-proposal.html>
now.
Daryle W.
Great! Thank you.
I'm not an expert norm reader, but it looks like it takes into account most
of what has been said here so far.

The "set of source classes" is a good idea to make things simpler. Can you
clarify what you mean by a class "sourcing" another one?

Regarding your interrogation on the "most derived class", I may be wrong
but I think it actually refers to the class being tested for being standard
layout. The issue is that inherited members are also members of the tested
class, so simply saying "has no non-static data member" would prevent any
base class from having non-static data members as well, hence the emphasis
on "most derived". It should probably be read like "does not declare any
non-static data member", but I agree the wording is confusing.

Oh and my name is Corentin Schreiber, by the way.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Daryle Walker
2014-01-24 18:22:20 UTC
Permalink
Post by c***@cea.fr
Post by Daryle Walker
Post by Daryle Walker
Post by c***@cea.fr
Another thing that comes to my mind, things would much simpler if we were
A a{.i=0, .k=2}; // compiles everywhere
A a{.i=0, .j=1, .k=2}; // compiles within friend or derived classes
This syntax could be allowed for any class, regardless of its
inheritance chain
and of the type of is members, as far as I can tell. I see that this
has already
https://groups.google.com/a/isocpp.org/forum/#!msg/std-
proposals/IgDFqKjKlRs/CGARpDJy9JsJ
It seems that they are only targeting aggregate types, so we might cooperate
to make things better in both worlds, since I'm sure they don't need
the current
restrictions of aggregate types and would beneficiate from relaxing
these as we
are discussing here.
I'm the writer of that proposal, and I added trial prose about expanded
aggregates, based on this thread. But I'm going to undo that draft and
propose expanded aggregates separately, as doing them together showed that
the mix was a bad idea. The aggregate expansion prose mostly gets lost in
the designated initializer prose, except for the parts that stick out
badly. Both proposals will be independently based off the latest C++ draft,
and can't reference each other (yet).
I've uploaded a draft proposal for expanded aggregates<http://htmlpreview.github.io/?https://raw.github.com/CTMacUser/multiarray-iso-proposal/master/expanded-aggregate-proposal.html>
now.
Daryle W.
Great! Thank you.
I'm not an expert norm reader, but it looks like it takes into account
most of what has been said here so far.
The "set of source classes" is a good idea to make things simpler. Can you
clarify what you mean by a class "sourcing" another one?
If aggregate class A sources aggregate class B, then B contains non-static
data members and A references those same members during its initialization.
Note that A and B may be the same type. If A's set of source classes is
empty, A is still a single-source class and sources itself, so I wouldn't
have to make a special case for completely empty classes. I did not define
"sourcing;" I don't know if I should formally define it or if I should
rephrase those parts of the prose. ("Sourcing" assumes the class is
single-source since its meaning is ambiguous when the set of source class
has more than one element.)
Post by c***@cea.fr
Regarding your interrogation on the "most derived class", I may be wrong
but I think it actually refers to the class being tested for being standard
layout. The issue is that inherited members are also members of the tested
class, so simply saying "has no non-static data member" would prevent any
base class from having non-static data members as well, hence the emphasis
on "most derived". It should probably be read like "does not declare any
non-static data member", but I agree the wording is confusing.
I think the term "most derived class" means the object you have a reference
to is not of the declared class, but it's actually a base-class sub-object
and the full object is of a derived class (from the declared class). The
section about standard-layout classes examine classes as themselves and not
with any associated objects, so the term "most derived class" is
inappropriate in that context. I think an editorial bug should be filed on
it. (But my change obliterates that bug anyway.)

If a class inherits multiply from a base class, and at least one of those
inheritances is not virtual, then the class has multiple copies of that
base class sub-object, and therefore multiple-copies of that base class'
non-static data members. Such a class can't be single-source, since you
couldn't describe all members of all copies in a single aggregate
initialization (without complicating the syntax with a new separator). I
wonder if the writers of the standard-layout section didn't really mean
single-source instead of at-most-one-source-class.
--
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT gmail DOT com
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Daryle Walker
2014-01-25 05:01:03 UTC
Permalink
Post by Daryle Walker
Post by Daryle Walker
Post by c***@cea.fr
Another thing that comes to my mind, things would much simpler if we were
A a{.i=0, .k=2}; // compiles everywhere
A a{.i=0, .j=1, .k=2}; // compiles within friend or derived classes
This syntax could be allowed for any class, regardless of its
inheritance chain
and of the type of is members, as far as I can tell. I see that this has
already
https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IgDFqKjKlRs/CGARpDJy9JsJ
It seems that they are only targeting aggregate types, so we might cooperate
to make things better in both worlds, since I'm sure they don't need the
current
restrictions of aggregate types and would beneficiate from relaxing
these as we
are discussing here.
I'm the writer of that proposal, and I added trial prose about expanded
aggregates, based on this thread. But I'm going to undo that draft and
propose expanded aggregates separately, as doing them together showed that
the mix was a bad idea. The aggregate expansion prose mostly gets lost in
the designated initializer prose, except for the parts that stick out
badly. Both proposals will be independently based off the latest C++ draft,
and can't reference each other (yet).
I've uploaded a draft proposal for expanded aggregates<http://htmlpreview.github.io/?https://raw.github.com/CTMacUser/multiarray-iso-proposal/master/expanded-aggregate-proposal.html>
now.
Daryle W.
I uploaded a new version. It adds something I had in my original merged
aggregate/designated-initializer paper, but forgot to transfer. A (new
style) aggregate class that gets its data from a base class is essentially
a proxy for that base class. So when the base class is virtual, the
aggregate class that derives from it, when used as a direct base class
itself, has to have the same restrictions a virtual base class would have.

12.6.2/7 was already amended to say an aggregate base class that derives
from a virtual class is also its base-initializer ignored when the
constructor's class is not the most derived class.

12.6.2/5 is now amended that a constructor's base-initializer section gets
a duplicate member error is there's an initializer for a
data-bearing virtual base class and an aggregate direct base class that
also derives from the virtual base class (or two aggregate direct base
classes that derive from the same virtual base class).

struct A { int a, b = 1; };
struct B : public virtual A { };
struct C : protected virtual A { };
class E;
struct D : protected B, private C { friend class E; D(); };
class E : D { E(); };


The constructor of D can specify at most one of {A, B, C} as a base
initializer. Whichever one is chosen, the constructor of E will ignore it.
No matter if E's constructor explicitly calls D's constructor, E's
constructor must aggregate-initialize A if it doesn't want the A sub-object
default-initialized.

Daryle W.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
c***@cea.fr
2014-08-27 21:26:00 UTC
Permalink
Post by Daryle Walker
Post by Daryle Walker
Post by Daryle Walker
Post by c***@cea.fr
Another thing that comes to my mind, things would much simpler if we were
A a{.i=0, .k=2}; // compiles everywhere
A a{.i=0, .j=1, .k=2}; // compiles within friend or derived classes
This syntax could be allowed for any class, regardless of its
inheritance chain
and of the type of is members, as far as I can tell. I see that this
has already
https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IgDFqKjKlRs/CGARpDJy9JsJ
It seems that they are only targeting aggregate types, so we might cooperate
to make things better in both worlds, since I'm sure they don't need
the current
restrictions of aggregate types and would beneficiate from relaxing
these as we
are discussing here.
I'm the writer of that proposal, and I added trial prose about expanded
aggregates, based on this thread. But I'm going to undo that draft and
propose expanded aggregates separately, as doing them together showed that
the mix was a bad idea. The aggregate expansion prose mostly gets lost in
the designated initializer prose, except for the parts that stick out
badly. Both proposals will be independently based off the latest C++ draft,
and can't reference each other (yet).
I've uploaded a draft proposal for expanded aggregates
<http://htmlpreview.github.io/?https://raw.github.com/CTMacUser/multiarray-iso-proposal/master/expanded-aggregate-proposal.html>
now.
Daryle W.
I uploaded a new version. It adds something I had in my original merged
aggregate/designated-initializer paper, but forgot to transfer. A (new
style) aggregate class that gets its data from a base class is essentially
a proxy for that base class. So when the base class is virtual, the
aggregate class that derives from it, when used as a direct base class
itself, has to have the same restrictions a virtual base class would have.
12.6.2/7 was already amended to say an aggregate base class that derives
from a virtual class is also its base-initializer ignored when the
constructor's class is not the most derived class.
12.6.2/5 is now amended that a constructor's base-initializer section gets
a duplicate member error is there's an initializer for a
data-bearing virtual base class and an aggregate direct base class that
also derives from the virtual base class (or two aggregate direct base
classes that derive from the same virtual base class).
struct A { int a, b = 1; };
struct B : public virtual A { };
struct C : protected virtual A { };
class E;
struct D : protected B, private C { friend class E; D(); };
class E : D { E(); };
The constructor of D can specify at most one of {A, B, C} as a base
initializer. Whichever one is chosen, the constructor of E will ignore
it. No matter if E's constructor explicitly calls D's constructor, E's
constructor must aggregate-initialize A if it doesn't want the A
sub-object default-initialized.
Daryle W.
Hello Daryle.

How is this proposal going? Did you get any feedback?

Best,
Corentin Schreiber.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2014-08-27 21:30:59 UTC
Permalink
Post by c***@cea.fr
Hello Daryle.
How is this proposal going? Did you get any feedback?
It hasn't been presented to the committee, but EWG is interested:
http://cplusplus.github.io/EWG/ewg-active.html#108
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Daryle Walker
2014-09-18 10:27:48 UTC
Permalink
Oh, I haven't touched this stuff since the spring. And just checked my
e-mail now. Does anyone see any problems with the proposal?

I don't know if Gabriel Dos Reis has tried to contact me.

On Wed, Aug 27, 2014 at 5:30 PM, Ville Voutilainen <
Post by Ville Voutilainen
Post by c***@cea.fr
Hello Daryle.
How is this proposal going? Did you get any feedback?
http://cplusplus.github.io/EWG/ewg-active.html#108
--
---
You received this message because you are subscribed to a topic in the
Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/isocpp.org/d/topic/std-proposals/77IY0cAlYR8/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT gmail DOT com
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2014-09-18 11:09:13 UTC
Permalink
Post by Daryle Walker
Oh, I haven't touched this stuff since the spring. And just checked my
e-mail now. Does anyone see any problems with the proposal?
I don't know if Gabriel Dos Reis has tried to contact me.
You could contact him. :) I can certainly introduce you if you want.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
e***@live.com
2014-01-25 12:53:31 UTC
Permalink
Inheritance based polymorphic is bad. It just like "goto", "c-style-array".
It makes us difficult to manage resources, and make C++ slower and
difficult to use. Its implements still have problems

I think concept-based polymorphic is the true polymorphic.
I have put my sample on the skydrive .
*https://skydrive.live.com/redir?resid=FB612199F19B150B%21105*<https://skydrive.live.com/redir?resid=FB612199F19B150B%21105>
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michał Dominiak
2014-01-25 14:34:57 UTC
Permalink
This post is a nice proof why posting rights should be provided after
passing at least some basic programming AND English test.
Post by e***@live.com
Inheritance based polymorphic is bad. It just like "goto", "c-style-array".
It makes us difficult to manage resources, and make C++ slower and
difficult to use. Its implements still have problems
I think concept-based polymorphic is the true polymorphic.
I have put my sample on the skydrive .
*https://skydrive.live.com/redir?resid=FB612199F19B150B%21105*<https://skydrive.live.com/redir?resid=FB612199F19B150B%21105>
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Olaf van der Spek
2014-02-05 11:46:33 UTC
Permalink
Supporting base classes without non-static data members and supporting
virtual functions seems simple.

Allowing initialization of base class members seems a bit fragile as you'd
depend on the order of a lot of definitions.
What about supporting classes with default constructors? The default
constructor could be run first after which public data members could be
initialized.
--
---
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Continue reading on narkive:
Loading...