Topic: Named function parameters using anonymous


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 16 Jun 2014 12:33:28 -0700
Raw View
Em seg 16 jun 2014, =E0s 12:18:51, Matthew Fioravante escreveu:
> That also implies adding support for C tagged structure initialization to=
=20
> C++, which implies defining how it works with constructors. At first pass=
,=20
> I'd say only enable the syntax for POD structs. This would need to be=20
> studied very carefully. I wouldn't be surprised if this was already broug=
ht=20
> up in the past, studied, and rejected for some reason. Does anyone have
> insight on that? Google doesn't appear to be helpful.
> =20

The interaction with constructors could be just the same as named arguments=
 to=20
the constructor.

Examples:

struct NoConstructor
{
 int x;
 int y;
};
NoConstructor nc { .x =3D 1, .y =3D 2 };

class Constructor
{
 int m_x;
 int m_y;
public:
 constexpr Constructor(int x, int y) : m_x(x), m_y(y) {}
};
Constructor c { .x =3D 1, .y =3D 2 };

In other words, an aggregate with no constructors declared is equivalent to=
=20
having constructors taking the exact same types as the members, with the sa=
me=20
names, with every argument having as default the default construction of th=
e=20
type in question.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Mon, 16 Jun 2014 13:14:42 -0700 (PDT)
Raw View
------=_Part_985_25664910.1402949682704
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Monday, June 16, 2014 3:33:32 PM UTC-4, Thiago Macieira wrote:
>
> Em seg 16 jun 2014, =C3=A0s 12:18:51, Matthew Fioravante escreveu:=20
> > That also implies adding support for C tagged structure initialization=
=20
> to=20
> > C++, which implies defining how it works with constructors. At first=20
> pass,=20
> > I'd say only enable the syntax for POD structs. This would need to be=
=20
> > studied very carefully. I wouldn't be surprised if this was already=20
> brought=20
> > up in the past, studied, and rejected for some reason. Does anyone have=
=20
> > insight on that? Google doesn't appear to be helpful.=20
> >  =20
>
> The interaction with constructors could be just the same as named=20
> arguments to=20
> the constructor.=20
>
> Examples:=20
>
> struct NoConstructor=20
> {=20
>         int x;=20
>         int y;=20
> };=20
> NoConstructor nc { .x =3D 1, .y =3D 2 };=20
>
> class Constructor=20
> {=20
>         int m_x;=20
>         int m_y;=20
> public:=20
>         constexpr Constructor(int x, int y) : m_x(x), m_y(y) {}=20
> };=20
> Constructor c { .x =3D 1, .y =3D 2 };=20
>
> In other words, an aggregate with no constructors declared is equivalent=
=20
> to=20
> having constructors taking the exact same types as the members, with the=
=20
> same=20
> names, with every argument having as default the default construction of=
=20
> the=20
> type in question.=20
>

I agree, and actually this would be useful in other areas because many=20
times I've been forced to write a stupid forwarding constructor for struct=
=20
types which I used internally to implement classes. One major advantage of=
=20
these compiler generated forwarding constructors is that it can handle=20
perfect forwarding exactly for all combinations of lvalues and rvalues.

What we're essentially doing is adding a compiler generated default=20
constructor which takes a set of arguments equal to the data members. This=
=20
does not make sense at all unless all data members are public.

Now we have opened pandora's box. If we take this step, a lot of questions=
=20
follow:

Do we need to support =3D default?

struct S {
  int x;
  int y;
  S(int x, int y) =3D default;
}
How do we "default" all of the lvalue/rvalue variations?

We probably also need =3D delete, if people want to disable this behavior.

What about inheritance? The below seems reasonable:

struct A {
  int a;
  int b;
};
=20
struct B : public A {
  int c;
  int d;
};

B b{ .a =3D 1, .b =3D 2, .c =3D3, .d =3D 4};=20

How about copy initialization?

B b =3D { a. =3D1 , b =3D .2, .c =3D 3, .d =3D 4};

How about assignment?

B b;
b =3D { a. =3D 1, ... };

If the {} expression produces an anonymous struct, that means we need some=
=20
kind of implicit conversion to B. How does this affect C compatibility?

How about unions?


A struct in this sense is really just a tuple with names, in some cases=20
more flexible than a tuple because the compiler is free to pad the members=
=20
however it likes. For example with the idea of an implicit struct wrapping=
=20
the call stack, the compiler can add padding for stack canaries and any=20
other implementation specific bits and still be compatible within the rules=
=20
of a C++ struct. You can compose structs with inheritance. You can=20
selectively initialize them with the tagged syntax. You can pass them=20
around and their data members get copied/moved as necessary. We can call it=
=20
struct-ured programming (new buzzword!).

This would take a lot of effort to iron out all of the little details.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_985_25664910.1402949682704
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Monday, June 16, 2014 3:33:32 PM UTC-4, Thiago =
Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Em seg 16 jun 2=
014, =C3=A0s 12:18:51, Matthew Fioravante escreveu:
<br>&gt; That also implies adding support for C tagged structure initializa=
tion to=20
<br>&gt; C++, which implies defining how it works with constructors. At fir=
st pass,=20
<br>&gt; I'd say only enable the syntax for POD structs. This would need to=
 be=20
<br>&gt; studied very carefully. I wouldn't be surprised if this was alread=
y brought=20
<br>&gt; up in the past, studied, and rejected for some reason. Does anyone=
 have
<br>&gt; insight on that? Google doesn't appear to be helpful.
<br>&gt; &nbsp;
<br>
<br>The interaction with constructors could be just the same as named argum=
ents to=20
<br>the constructor.
<br>
<br>Examples:
<br>
<br>struct NoConstructor
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int x;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int y;
<br>};
<br>NoConstructor nc { .x =3D 1, .y =3D 2 };
<br>
<br>class Constructor
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int m_x;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int m_y;
<br>public:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constexpr Constructor(i=
nt x, int y) : m_x(x), m_y(y) {}
<br>};
<br>Constructor c { .x =3D 1, .y =3D 2 };
<br>
<br>In other words, an aggregate with no constructors declared is equivalen=
t to=20
<br>having constructors taking the exact same types as the members, with th=
e same=20
<br>names, with every argument having as default the default construction o=
f the=20
<br>type in question.
<br></blockquote><div><br>I agree, and actually this would be useful in oth=
er areas because many times I've been forced to write a stupid forwarding c=
onstructor for struct types which I used internally to implement classes. O=
ne major advantage of these compiler generated forwarding constructors is t=
hat it can handle perfect forwarding exactly for all combinations of lvalue=
s and rvalues.<br><br>What we're essentially doing is adding a compiler gen=
erated default constructor which takes a set of arguments equal to the data=
 members. This does not make sense at all unless all data members are publi=
c.<br><br>Now we have opened pandora's box. If we take this step, a lot of =
questions follow:<br><br>Do we need to support =3D default?<br><br>struct S=
 {<br>&nbsp; int x;<br>&nbsp; int y;<br>&nbsp; S(int x, int y) =3D default;=
<br>}<br>How do we "default" all of the lvalue/rvalue variations?<br><br>We=
 probably also need =3D delete, if people want to disable this behavior.<br=
><br>What about inheritance? The below seems reasonable:<br><br>struct A {<=
br>&nbsp; int a;<br>&nbsp; int b;<br>};<br>&nbsp;<br>struct B : public A {<=
br>&nbsp; int c;<br>&nbsp; int d;<br>};<br></div><div><br>B b{ .a =3D 1, .b=
 =3D 2, .c =3D3, .d =3D 4}; <br><br>How about copy initialization?<br><br>B=
 b =3D { a. =3D1 , b =3D .2, .c =3D 3, .d =3D 4};<br><br>How about assignme=
nt?<br><br>B b;<br>b =3D { a. =3D 1, ... };<br><br>If the {} expression pro=
duces an anonymous struct, that means we need some kind of implicit convers=
ion to B. How does this affect C compatibility?<br><br>How about unions?<br=
><br><br>A struct in this sense is really just a tuple with names, in some =
cases more flexible than a tuple because the compiler is free to pad the=20
members however it likes. For example with the idea of an implicit struct w=
rapping the call stack, the compiler can add padding for=20
stack canaries and any other implementation specific bits and still be=20
compatible within the rules of a C++ struct. You can compose structs=20
with inheritance. You can selectively initialize them with the tagged synta=
x. You can pass them
 around and their data members get copied/moved as necessary. We can call i=
t struct-ured programming (new buzzword!).<br><br>This would take a lot of =
effort to iron out all of the little details.<br><br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_985_25664910.1402949682704--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 16 Jun 2014 14:51:24 -0700
Raw View
Em seg 16 jun 2014, =E0s 13:14:42, Matthew Fioravante escreveu:
> I agree, and actually this would be useful in other areas because many
> times I've been forced to write a stupid forwarding constructor for struc=
t
> types which I used internally to implement classes. One major advantage o=
f
> these compiler generated forwarding constructors is that it can handle
> perfect forwarding exactly for all combinations of lvalues and rvalues.

It's also a trivial constructor if the types are trivial, constexpr if the=
=20
types are literal, etc.

> What we're essentially doing is adding a compiler generated default
> constructor which takes a set of arguments equal to the data members. Thi=
s
> does not make sense at all unless all data members are public.

Correct, but that doesn't change brace initialisation. You can't do that fo=
r=20
non-public members:

<stdin>:1:26: error: no matching constructor for initialization of 'X'
class X { int x, y; }; X x =3D { 1 };
[...]
<stdin>:1:7: note: candidate constructor (the implicit default constructor)=
=20
not viable: requires 0 arguments, but 1 was provided

> Now we have opened pandora's box. If we take this step, a lot of question=
s
> follow:
>=20
> Do we need to support =3D default?
>=20
> struct S {
>   int x;
>   int y;
>   S(int x, int y) =3D default;
> }
> How do we "default" all of the lvalue/rvalue variations?

Hmm... that's a good question. Maybe if you default the default constructor=
,=20
it should just work. GCC, Clang and ICC appear to already work like that.

struct S {
 int x;
 int y;
 S(const S &) =3D delete;
 S() =3D default;
};
S s { 1 };

This 1-argument constructing is matching the implicit default constructor. =
If=20
you remove the "=3D default" part, then the compiler complains that it can'=
t=20
match to any constructor.

> We probably also need =3D delete, if people want to disable this behavior=
..

As above: just delete the default constructor.

> What about inheritance? The below seems reasonable:
>=20
> struct A {
>   int a;
>   int b;
> };
>=20
> struct B : public A {
>   int c;
>   int d;
> };
>=20
> B b{ .a =3D 1, .b =3D 2, .c =3D3, .d =3D 4};

This does not exist in C, so we're in new territory here. In C++98, B wasn'=
t=20
eligible for brace initialisation because it wasn't POD. With C++11, it's n=
ow=20
trivial layout and trivially initialisable, but it's still not brace-
initialisable.

I don't see a need to change. You must provide a constructor if you want th=
e=20
above to work:

 constexpr B(int a, int b, int c, int d) : A{a, b}, c{c}, d{d} {}

> How about copy initialization?
>=20
> B b =3D { a. =3D1 , b =3D .2, .c =3D 3, .d =3D 4};

Same rules as from pre-history: the copy constructor is elided and you just=
=20
call the default constructor above. It needs to be supported for C99=20
compatibility too.

> How about assignment?
>=20
> B b;
> b =3D { a. =3D 1, ... };

This is a different one. It probably should not work as written. But this=
=20
should:

 B b;
 b =3D B{ .a =3D 1 };
 b =3D B(.a =3D 1);

> If the {} expression produces an anonymous struct, that means we need som=
e
> kind of implicit conversion to B. How does this affect C compatibility?
>=20
> How about unions?

You can initialise at most one element. Right now, for:

union U { int i; double d; };

The following works:
 U u1 =3D {};
 U u2 =3D { 1 };

But this doesn't:
 U u3 =3D { 1.0 };
due to narrowing of double to int, when trying to initialise U(int) [it wor=
ks=20
in C++98 and in C, but produces possibly unexpected results]. This works in=
=20
C99:

 union U u4 =3D { .d =3D 1.0 };

So we should allow in C++ too. So the rule for unions is that the default=
=20
constructor is equivalent to one-argument constructors taking each of the=
=20
members, with the exact same access level, type and name.

The interesting thing here will be dealing with C++11's unrestricted unions=
:=20
the constructor gets deleted by default if any of the members has a non-
trivial constructor (e.g., add std::string s; to the union above). We can=
=20
bring them back:

union U {
 int i;
 std::string s;
 constexpr U(int i) : i(i) {}
 U(std::string s) : s(s) {}
 ~U() {}
};

Should there be a shortcut that allows us to get the per-element constructo=
rs?=20
By the way, if you write ~U() =3D default; the destructor is still deleted.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Mon, 16 Jun 2014 17:36:58 -0700 (PDT)
Raw View
------=_Part_1889_18961131.1402965419142
Content-Type: text/plain; charset=UTF-8



On Monday, June 16, 2014 5:51:31 PM UTC-4, Thiago Macieira wrote:
>
> > What we're essentially doing is adding a compiler generated default
> > constructor which takes a set of arguments equal to the data members.
> This
> > does not make sense at all unless all data members are public.
>
> Correct, but that doesn't change brace initialisation. You can't do that
> for
> non-public members:
>

Actually now that I think about it that doesn't make sense. Braced
initialization is not creating new constructors. Its just another C
compatible magic abomination which lets you initialize structs. For C
compatibility, tagged initialization syntax should work the same way as
braced initialization syntax, and Daryle's proposal seems to be providing
just that.

Now we are discussing something entirely different. That is compiler
generated default constructors for structs which have a parameter list
matching the data members. In this case, initializing the data members by
name will depend on a named function argument proposal, either the idea
sketched earlier here or another implementation.

We already get this from C and Daryle's proposal:
struct S { int x; int y; };
1) S s{1, 2};
2) S s{.y = 2};

Adding actual constructors to the mix, gives us these:
3) S s(1, 2);
4) S s(.y = 2); //Depends on a named function arguments proposal

std::vector<S> s;
5) s.emplace_back(1, 2);
6) s.emplace_back(.y = 2); //This would be nice

I think the emplace_back() example (5) here is a real issue. We should be
able to perfect forward the struct initialization syntax for both tagged
and non-tagged braced initialization. Having an actual constructor for S
generated by the compiler would allow perfect forwarding to work for (5)
and also give us (3) . Adding named function parameters on top of that
would enable (4) and (6).

By adding the compiler generated member constructor, we get perfect
forwarding to work here in emplace_back and other forwarding functions
which I believe is a good thing. Now there is a complication where when you
initialize a struct, sometimes you're doing this magic C brace thing, and
other times you're calling a constructor.

S s{1, 2}; //C brace init magic thing
S s(1, 2); //Constructor call
v.emplace_back(1, 2); //Constructor call

BIG QUESTION: *Does this difference actually mean anything in practice
anywhere?* If it does that's another stupid esoteric C++ rule that people
have to learn. That's a big problem. I hate those with a passion and would
really not like to introduce more.

Some solutions to this:
1) Do nothing. If the semantics are exactly the same, and only language
lawyers need to know the difference then its probably fine.
2) Change {} initialization to call the constructor. Actually this can be
accomplished by simply removing the C brace initialization rules from the
standard. The syntax would then "fall back" to just being a constructor
call. For all purposes of C compatibility, the semantics would have to be
the same. This would also mean we don't need Daryle's proposal at all,
because named function parameters would also give us the tagged brace
initialization syntax for free.


>
> > struct S {
> >   int x;
> >   int y;
> >   S(int x, int y) = default;
> > }
> > How do we "default" all of the lvalue/rvalue variations?
>
> Hmm... that's a good question. Maybe if you default the default
> constructor,
> it should just work. GCC, Clang and ICC appear to already work like that.
>

It looks like on gcc 4.9 you can still use brace and tagged initialization
even if you delete the default constructor. Its only when you define
another constructor that braced initialization gets disabled. Was that an
oversight in C++11? Tieing C compatible braced and tagged initialization to
the default constructor seems like a better idea than depending on whether
a user defined constructor was written.

If I delete the default constructor, I should disable brace init as well.
Removing brace init in favor of implict constructors would fix this problem
as well.


> What about inheritance? The below seems reasonable:
> >
> > struct A {
> >   int a;
> >   int b;
> > };
> >
> > struct B : public A {
> >   int c;
> >   int d;
> > };
> >
> > B b{ .a = 1, .b = 2, .c =3, .d = 4};
>
> This does not exist in C, so we're in new territory here. In C++98, B
> wasn't
> eligible for brace initialisation because it wasn't POD. With C++11, it's
> now
> trivial layout and trivially initialisable, but it's still not brace-
> initialisable.
>
> I don't see a need to change. You must provide a constructor if you want
> the
> above to work:
>
>         constexpr B(int a, int b, int c, int d) : A{a, b}, c{c}, d{d} {}
>

I suppose that's fair. If you want to compose structs you can just use
containment instead of inheritance. Containment also avoids name clashes if
you have multiple inheritance and 2 base classes with the same data member
names.


>
> > How about copy initialization?
> >
> > B b = { a. =1 , b = .2, .c = 3, .d = 4};
>
> Same rules as from pre-history: the copy constructor is elided and you
> just
> call the default constructor above. It needs to be supported for C99
> compatibility too.
>
> > How about assignment?
> >
> > B b;
> > b = { a. = 1, ... };
>
> This is a different one. It probably should not work as written. But this
> should:
>
>         B b;
>         b = B{ .a = 1 };
>

Seems ok, if tagged initialization is not actually defining a new
constructor and works like brace initialization.


>         b = B(.a = 1);
>

This should fail to compile, unless we have these implicit constructors and
named constructor arguments.


>
> > If the {} expression produces an anonymous struct, that means we need
> some
> > kind of implicit conversion to B. How does this affect C compatibility?
> >
> > How about unions?
>
> You can initialise at most one element. Right now, for:
>
> union U { int i; double d; };
>
> The following works:
>         U u1 = {};
>         U u2 = { 1 };
>
> But this doesn't:
>         U u3 = { 1.0 };
> due to narrowing of double to int, when trying to initialise U(int) [it
> works
> in C++98 and in C, but produces possibly unexpected results]. This works
> in
> C99:
>
>         union U u4 = { .d = 1.0 };
>

So we should allow in C++ too.


Pretty straightforward for the C tagged syntax if that is to be adopted.

So the rule for unions is that the default
> constructor is equivalent to one-argument constructors taking each of the
> members, with the exact same access level, type and name.
>
> The interesting thing here will be dealing with C++11's unrestricted
> unions:
> the constructor gets deleted by default if any of the members has a non-
> trivial constructor (e.g., add std::string s; to the union above). We can
> bring them back:
>
> union U {
>         int i;
>         std::string s;
>         constexpr U(int i) : i(i) {}
>         U(std::string s) : s(s) {}
>         ~U() {}
> };
>

Unions are an interesting case here.

I think disabling the default constructor is somewhat misguided. It seems
like a way of promoting encapsulation within the union, that is making
union more like a class and more "safe". You can even add member functions
to a union, which to me seems almost useless as you don't know which member
is active.

The problem is that its still very easy to access an uninitialized object.
You cannot encapsulate all of the initialized objects with a union alone
because at minimum you need one more piece of external state, that is a tag
to tell you which object is active. For that, you have to wrap the union in
a class if you want to protect it. Therefore, unions should be thought of
more like structs than classes. I wish the standard would stop trying to
protect us from ourselves here. If you are using union, you are pointing
the loaded gun at your foot and you know it so everyone should get out of
the way. The C++03 restrictions were arbitrary and extremely annoying.

The empty constructor is somewhat dangerous, because all it does is leave
the entire union in an undefined state. However it could be useful, if we
enable the below:

union U {
int x = 2;
int y;
std::string s;
};

U u; //<-default constructor U::U() will initialized x to 2, x is the
active object.

union V {
int x = 2;
int y = 3; //compiler error, as before. Multiple fields initialized.
};

union T {
std::string s = {};
std::vector<int> v;
};

T t; //<-Initializes the string member


Now we can also add explicit default constructors for all of the union
members and get the brace initialization syntax back again.

One potential ambiguity:

union U {
std::string s;
std::string v;
};

Which one does U::U(std::string) initialize? Maybe it doesn't matter? Since
they both occupy the same memory we could just say the first one, or which
one is implementation defined. Maybe its a compiler error, but that could
break legacy code.

Finally, now we get to tagged initialization. With C tagged init syntax,
everything works just fine.

U u { .s = "hello" };

With constructors with named arguments, maybe it doesn't work.

U u(.s = "hello");

How does the above know which single argument constructor to call? Deduce
the types from the initializers and look at the names? I think this is a
general conflict when combining overloading and named function parameters
that needs to be resolved.



>
> Should there be a shortcut that allows us to get the per-element
> constructors?
>

Not sure what you mean here?


> By the way, if you write ~U() = default; the destructor is still deleted.
>
>
This is fine. I don't think it ever makes sense to write a destructor for a
union because you don't know which member to destruct. This probably should
stay deleted.


> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>       PGP/GPG: 0x6EF45358; fingerprint:
>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>


Ok, after all that my head hurts.

--

---
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+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1889_18961131.1402965419142
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Monday, June 16, 2014 5:51:31 PM UTC-4, Thiago =
Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; What we're=
 essentially doing is adding a compiler generated default
<br>&gt; constructor which takes a set of arguments equal to the data membe=
rs. This
<br>&gt; does not make sense at all unless all data members are public.
<br>
<br>Correct, but that doesn't change brace initialisation. You can't do tha=
t for=20
<br>non-public members:
<br></blockquote><div><br>Actually now that I think about it that doesn't m=
ake sense. Braced initialization is not creating new constructors. Its just=
 another C compatible magic abomination which lets you initialize structs. =
For C compatibility, tagged initialization syntax should work the same way =
as braced initialization syntax, and Daryle's proposal seems to be providin=
g just that.<br><br>Now we are discussing something entirely different. Tha=
t is compiler generated default constructors for structs which have a param=
eter list matching the data members. In this case, initializing the data me=
mbers by name will depend on a named function argument proposal, either the=
 idea sketched earlier here or another implementation.<br><br>We already ge=
t this from C and Daryle's proposal:<br>struct S { int x; int y; };<br>1) S=
 s{1, 2};<br>2) S s{.y =3D 2};<br><br>Adding actual constructors to the mix=
, gives us these:<br>3) S s(1, 2);<br>4) S s(.y =3D 2); //Depends on a name=
d function arguments proposal<br><br>std::vector&lt;S&gt; s;<br>5) s.emplac=
e_back(1, 2);<br>6) s.emplace_back(.y =3D 2); //This would be nice<br><br>I=
 think the emplace_back() example (5) here is a real issue. We should be ab=
le to perfect forward the struct initialization syntax for both tagged and =
non-tagged braced initialization. Having an actual constructor for S genera=
ted by the compiler would allow perfect forwarding to work for (5) and also=
 give us (3) . Adding named function parameters on top of that would enable=
 (4) and (6).<br><br>By adding the compiler generated member constructor, w=
e get perfect forwarding to work here in emplace_back and other forwarding =
functions which I believe is a good thing. Now there is a complication wher=
e when you initialize a struct, sometimes you're doing this magic C brace t=
hing, and other times you're calling a constructor.<br><br>S s{1, 2}; //C b=
race init magic thing<br>S s(1, 2); //Constructor call<br>v.emplace_back(1,=
 2); //Constructor call<br><br>BIG QUESTION: <b>Does this difference actual=
ly mean anything in practice anywhere?</b> If it does that's another stupid=
 esoteric C++ rule that people have to learn. That's a big problem. I hate =
those with a passion and would really not like to introduce more.<br><br>So=
me solutions to this:<br>1) Do nothing. If the semantics are exactly the sa=
me, and only language lawyers need to know the difference then its probably=
 fine.<br>2) Change {} initialization to call the constructor. Actually thi=
s can be accomplished by simply removing the C brace initialization rules f=
rom the standard. The syntax would then "fall back" to just being a constru=
ctor call. For all purposes of C compatibility, the semantics would have to=
 be the same. This would also mean we don't need Daryle's proposal at all, =
because named function parameters would also give us the tagged brace initi=
alization syntax for free.<br><br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">&gt;=20
<br>&gt; struct S {
<br>&gt; &nbsp; int x;
<br>&gt; &nbsp; int y;
<br>&gt; &nbsp; S(int x, int y) =3D default;
<br>&gt; }
<br>&gt; How do we "default" all of the lvalue/rvalue variations?
<br>
<br>Hmm... that's a good question. Maybe if you default the default constru=
ctor,=20
<br>it should just work. GCC, Clang and ICC appear to already work like tha=
t.
<br></blockquote><div><br>It looks like on gcc 4.9 you can still use brace =
and tagged initialization even if you delete the default constructor. Its o=
nly when you define another constructor that braced initialization gets dis=
abled. Was that an oversight in C++11? Tieing C compatible braced and tagge=
d initialization to the default constructor seems like a better idea than d=
epending on whether a user defined constructor was written. <br><br>If I de=
lete the default constructor, I should disable brace init as well. Removing=
 brace init in favor of implict constructors would fix this problem as well=
..<br><br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; What a=
bout inheritance? The below seems reasonable:
<br>&gt;=20
<br>&gt; struct A {
<br>&gt; &nbsp; int a;
<br>&gt; &nbsp; int b;
<br>&gt; };
<br>&gt;=20
<br>&gt; struct B : public A {
<br>&gt; &nbsp; int c;
<br>&gt; &nbsp; int d;
<br>&gt; };
<br>&gt;=20
<br>&gt; B b{ .a =3D 1, .b =3D 2, .c =3D3, .d =3D 4};
<br>
<br>This does not exist in C, so we're in new territory here. In C++98, B w=
asn't=20
<br>eligible for brace initialisation because it wasn't POD. With C++11, it=
's now=20
<br>trivial layout and trivially initialisable, but it's still not brace-
<br>initialisable.
<br>
<br>I don't see a need to change. You must provide a constructor if you wan=
t the=20
<br>above to work:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constexpr B(int a, int =
b, int c, int d) : A{a, b}, c{c}, d{d} {}
<br></blockquote><div><br>I suppose that's fair. If you want to compose str=
ucts you can just use containment instead of inheritance. Containment also =
avoids name clashes if you have multiple inheritance and 2 base classes wit=
h the same data member names.<br>&nbsp;</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;">
<br>&gt; How about copy initialization?
<br>&gt;=20
<br>&gt; B b =3D { a. =3D1 , b =3D .2, .c =3D 3, .d =3D 4};
<br>
<br>Same rules as from pre-history: the copy constructor is elided and you =
just=20
<br>call the default constructor above. It needs to be supported for C99=20
<br>compatibility too.
<br>
<br>&gt; How about assignment?
<br>&gt;=20
<br>&gt; B b;
<br>&gt; b =3D { a. =3D 1, ... };
<br>
<br>This is a different one. It probably should not work as written. But th=
is=20
<br>should:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B b;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b =3D B{ .a =3D 1 };
<br></blockquote><div><br>Seems ok, if tagged initialization is not actuall=
y defining a new constructor and works like brace initialization.<br>&nbsp;=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;b =3D B(.a =3D 1);
<br></blockquote><div><br>This should fail to compile, unless we have these=
 implicit constructors and named constructor arguments. <br>&nbsp;</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">
<br>&gt; If the {} expression produces an anonymous struct, that means we n=
eed some
<br>&gt; kind of implicit conversion to B. How does this affect C compatibi=
lity?
<br>&gt;=20
<br>&gt; How about unions?
<br>
<br>You can initialise at most one element. Right now, for:
<br>
<br>union U { int i; double d; };
<br>
<br>The following works:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U u1 =3D {};
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U u2 =3D { 1 };
<br>
<br>But this doesn't:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U u3 =3D { 1.0 };
<br>due to narrowing of double to int, when trying to initialise U(int) [it=
 works=20
<br>in C++98 and in C, but produces possibly unexpected results]. This work=
s in=20
<br>C99:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;union U u4 =3D { .d =3D=
 1.0 };
<br>
&nbsp;</blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">So we shoul=
d allow in C++ too. </blockquote><div><br>Pretty straightforward for the C =
tagged syntax if that is to be adopted.<br><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;">So the rule for unions is that the default=20
<br>constructor is equivalent to one-argument constructors taking each of t=
he=20
<br>members, with the exact same access level, type and name.
<br>
<br>The interesting thing here will be dealing with C++11's unrestricted un=
ions:=20
<br>the constructor gets deleted by default if any of the members has a non=
-
<br>trivial constructor (e.g., add std::string s; to the union above). We c=
an=20
<br>bring them back:
<br>
<br>union U {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::string s;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constexpr U(int i) : i(=
i) {}
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U(std::string s) : s(s)=
 {}
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~U() {}
<br>};
<br></blockquote><div><br>Unions are an interesting case here.<br><br>I thi=
nk disabling the default constructor is somewhat misguided. It seems like a=
 way of promoting encapsulation within the union, that is making union more=
 like a class and more "safe". You can even add member functions to a union=
, which to me seems almost useless as you don't know which member is active=
.. <br><br>The problem is that its still very easy to access an uninitialize=
d object. You cannot encapsulate all of the initialized objects with a unio=
n alone because at minimum you need one more piece of external state, that =
is a tag to tell you which object is active. For that, you have to wrap the=
 union in a class if you want to protect it. Therefore, unions should be th=
ought of more like structs than classes. I wish the standard would stop try=
ing to protect us from ourselves here. If you are using union, you are poin=
ting the loaded gun at your foot and you know it so everyone should get out=
 of the way. The C++03 restrictions were arbitrary and extremely annoying. =
<br><br>The empty constructor is somewhat dangerous, because all it does is=
 leave the entire union in an undefined state. However it could be useful, =
if we enable the below:<br><br>union U {<br>int x =3D 2;<br>int y;<br>std::=
string s;<br>};<br><br>U u; //&lt;-default constructor U::U() will initiali=
zed x to 2, x is the active object.<br><br>union V {<br>int x =3D 2;<br>int=
 y =3D 3; //compiler error, as before. Multiple fields initialized.<br>};<b=
r><br>union T {<br>std::string s =3D {};<br>std::vector&lt;int&gt; v;<br>};=
<br><br>T t; //&lt;-Initializes the string member<br><br><br>Now we can als=
o add explicit default constructors for all of the union members and get th=
e brace initialization syntax back again.<br><br>One potential ambiguity:<b=
r><br>union U {<br>std::string s;<br>std::string v;<br>};<br><br>Which one =
does U::U(std::string) initialize? Maybe it doesn't matter? Since they both=
 occupy the same memory we could just say the first one, or which one is im=
plementation defined. Maybe its a compiler error, but that could break lega=
cy code.<br><br>Finally, now we get to tagged initialization. With C tagged=
 init syntax, everything works just fine.<br><br>U u { .s =3D "hello" };<br=
><br>With constructors with named arguments, maybe it doesn't work.<br><br>=
U u(.s =3D "hello"); <br><br>How does the above know which single argument =
constructor to call? Deduce the types from the initializers and look at the=
 names? I think this is a general conflict when combining overloading and n=
amed function parameters that needs to be resolved.<br><br>&nbsp;</div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">
<br>Should there be a shortcut that allows us to get the per-element constr=
uctors?=20
<br></blockquote><div><br>Not sure what you mean here?<br>&nbsp;</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;">By the way, if you write ~U() =3D d=
efault; the destructor is still deleted.
<br>
<br></blockquote><div><br>This is fine. I don't think it ever makes sense t=
o write a destructor for a union because you don't know which member to des=
truct. This probably should stay deleted.<br>&nbsp;</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQjCNEswDUBNCNanbu7euhq=
Ln_62FW8ag';return true;" onclick=3D"this.href=3D'http://www.google.com/url=
?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQjCNEswDUBNC=
Nanbu7euhqLn_62FW8ag';return true;">macieira.info</a> - thiago (AT) <a href=
=3D"http://kde.org" target=3D"_blank" onmousedown=3D"this.href=3D'http://ww=
w.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQj=
CNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;" onclick=3D"this.href=3D'http:=
//www.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75=
AFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;">kde.org</a>
<br>&nbsp; &nbsp;Software Architect - Intel Open Source Technology Center
<br>&nbsp; &nbsp; &nbsp; PGP/GPG: 0x6EF45358; fingerprint:
<br>&nbsp; &nbsp; &nbsp; E067 918B B660 DBD1 105C &nbsp;966C 33F5 F005 6EF4=
 5358
<br></blockquote><div><br><br>Ok, after all that my head hurts. <br></div><=
/div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1889_18961131.1402965419142--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Mon, 16 Jun 2014 17:45:09 -0700 (PDT)
Raw View
------=_Part_9_21739184.1402965909624
Content-Type: text/plain; charset=UTF-8

And one thing I got wrong, named function parameters won't enable this
syntax.

v.emplace_back(.y = 2);

I don't think this is actually possible. Unless variadic templates are
enhanced somehow with yet another feature to derive names for their
variadic arguments.

On Monday, June 16, 2014 8:36:59 PM UTC-4, Matthew Fioravante wrote:
>
>
>
> On Monday, June 16, 2014 5:51:31 PM UTC-4, Thiago Macieira wrote:
>>
>> > What we're essentially doing is adding a compiler generated default
>> > constructor which takes a set of arguments equal to the data members.
>> This
>> > does not make sense at all unless all data members are public.
>>
>> Correct, but that doesn't change brace initialisation. You can't do that
>> for
>> non-public members:
>>
>
> Actually now that I think about it that doesn't make sense. Braced
> initialization is not creating new constructors. Its just another C
> compatible magic abomination which lets you initialize structs. For C
> compatibility, tagged initialization syntax should work the same way as
> braced initialization syntax, and Daryle's proposal seems to be providing
> just that.
>
> Now we are discussing something entirely different. That is compiler
> generated default constructors for structs which have a parameter list
> matching the data members. In this case, initializing the data members by
> name will depend on a named function argument proposal, either the idea
> sketched earlier here or another implementation.
>
> We already get this from C and Daryle's proposal:
> struct S { int x; int y; };
> 1) S s{1, 2};
> 2) S s{.y = 2};
>
> Adding actual constructors to the mix, gives us these:
> 3) S s(1, 2);
> 4) S s(.y = 2); //Depends on a named function arguments proposal
>
> std::vector<S> s;
> 5) s.emplace_back(1, 2);
> 6) s.emplace_back(.y = 2); //This would be nice
>
> I think the emplace_back() example (5) here is a real issue. We should be
> able to perfect forward the struct initialization syntax for both tagged
> and non-tagged braced initialization. Having an actual constructor for S
> generated by the compiler would allow perfect forwarding to work for (5)
> and also give us (3) . Adding named function parameters on top of that
> would enable (4) and (6).
>
> By adding the compiler generated member constructor, we get perfect
> forwarding to work here in emplace_back and other forwarding functions
> which I believe is a good thing. Now there is a complication where when you
> initialize a struct, sometimes you're doing this magic C brace thing, and
> other times you're calling a constructor.
>
> S s{1, 2}; //C brace init magic thing
> S s(1, 2); //Constructor call
> v.emplace_back(1, 2); //Constructor call
>
> BIG QUESTION: *Does this difference actually mean anything in practice
> anywhere?* If it does that's another stupid esoteric C++ rule that people
> have to learn. That's a big problem. I hate those with a passion and would
> really not like to introduce more.
>
> Some solutions to this:
> 1) Do nothing. If the semantics are exactly the same, and only language
> lawyers need to know the difference then its probably fine.
> 2) Change {} initialization to call the constructor. Actually this can be
> accomplished by simply removing the C brace initialization rules from the
> standard. The syntax would then "fall back" to just being a constructor
> call. For all purposes of C compatibility, the semantics would have to be
> the same. This would also mean we don't need Daryle's proposal at all,
> because named function parameters would also give us the tagged brace
> initialization syntax for free.
>
>
> >
>> > struct S {
>> >   int x;
>> >   int y;
>> >   S(int x, int y) = default;
>> > }
>> > How do we "default" all of the lvalue/rvalue variations?
>>
>> Hmm... that's a good question. Maybe if you default the default
>> constructor,
>> it should just work. GCC, Clang and ICC appear to already work like that.
>>
>
> It looks like on gcc 4.9 you can still use brace and tagged initialization
> even if you delete the default constructor. Its only when you define
> another constructor that braced initialization gets disabled. Was that an
> oversight in C++11? Tieing C compatible braced and tagged initialization to
> the default constructor seems like a better idea than depending on whether
> a user defined constructor was written.
>
> If I delete the default constructor, I should disable brace init as well.
> Removing brace init in favor of implict constructors would fix this problem
> as well.
>
>
> > What about inheritance? The below seems reasonable:
>> >
>> > struct A {
>> >   int a;
>> >   int b;
>> > };
>> >
>> > struct B : public A {
>> >   int c;
>> >   int d;
>> > };
>> >
>> > B b{ .a = 1, .b = 2, .c =3, .d = 4};
>>
>> This does not exist in C, so we're in new territory here. In C++98, B
>> wasn't
>> eligible for brace initialisation because it wasn't POD. With C++11, it's
>> now
>> trivial layout and trivially initialisable, but it's still not brace-
>> initialisable.
>>
>> I don't see a need to change. You must provide a constructor if you want
>> the
>> above to work:
>>
>>         constexpr B(int a, int b, int c, int d) : A{a, b}, c{c}, d{d} {}
>>
>
> I suppose that's fair. If you want to compose structs you can just use
> containment instead of inheritance. Containment also avoids name clashes if
> you have multiple inheritance and 2 base classes with the same data member
> names.
>
>
>>
>> > How about copy initialization?
>> >
>> > B b = { a. =1 , b = .2, .c = 3, .d = 4};
>>
>> Same rules as from pre-history: the copy constructor is elided and you
>> just
>> call the default constructor above. It needs to be supported for C99
>> compatibility too.
>>
>> > How about assignment?
>> >
>> > B b;
>> > b = { a. = 1, ... };
>>
>> This is a different one. It probably should not work as written. But this
>> should:
>>
>>         B b;
>>         b = B{ .a = 1 };
>>
>
> Seems ok, if tagged initialization is not actually defining a new
> constructor and works like brace initialization.
>
>
>>         b = B(.a = 1);
>>
>
> This should fail to compile, unless we have these implicit constructors
> and named constructor arguments.
>
>
>>
>> > If the {} expression produces an anonymous struct, that means we need
>> some
>> > kind of implicit conversion to B. How does this affect C compatibility?
>> >
>> > How about unions?
>>
>> You can initialise at most one element. Right now, for:
>>
>> union U { int i; double d; };
>>
>> The following works:
>>         U u1 = {};
>>         U u2 = { 1 };
>>
>> But this doesn't:
>>         U u3 = { 1.0 };
>> due to narrowing of double to int, when trying to initialise U(int) [it
>> works
>> in C++98 and in C, but produces possibly unexpected results]. This works
>> in
>> C99:
>>
>>         union U u4 = { .d = 1.0 };
>>
>
> So we should allow in C++ too.
>
>
> Pretty straightforward for the C tagged syntax if that is to be adopted.
>
> So the rule for unions is that the default
>> constructor is equivalent to one-argument constructors taking each of the
>> members, with the exact same access level, type and name.
>>
>> The interesting thing here will be dealing with C++11's unrestricted
>> unions:
>> the constructor gets deleted by default if any of the members has a non-
>> trivial constructor (e.g., add std::string s; to the union above). We can
>> bring them back:
>>
>> union U {
>>         int i;
>>         std::string s;
>>         constexpr U(int i) : i(i) {}
>>         U(std::string s) : s(s) {}
>>         ~U() {}
>> };
>>
>
> Unions are an interesting case here.
>
> I think disabling the default constructor is somewhat misguided. It seems
> like a way of promoting encapsulation within the union, that is making
> union more like a class and more "safe". You can even add member functions
> to a union, which to me seems almost useless as you don't know which member
> is active.
>
> The problem is that its still very easy to access an uninitialized object.
> You cannot encapsulate all of the initialized objects with a union alone
> because at minimum you need one more piece of external state, that is a tag
> to tell you which object is active. For that, you have to wrap the union in
> a class if you want to protect it. Therefore, unions should be thought of
> more like structs than classes. I wish the standard would stop trying to
> protect us from ourselves here. If you are using union, you are pointing
> the loaded gun at your foot and you know it so everyone should get out of
> the way. The C++03 restrictions were arbitrary and extremely annoying.
>
> The empty constructor is somewhat dangerous, because all it does is leave
> the entire union in an undefined state. However it could be useful, if we
> enable the below:
>
> union U {
> int x = 2;
> int y;
> std::string s;
> };
>
> U u; //<-default constructor U::U() will initialized x to 2, x is the
> active object.
>
> union V {
> int x = 2;
> int y = 3; //compiler error, as before. Multiple fields initialized.
> };
>
> union T {
> std::string s = {};
> std::vector<int> v;
> };
>
> T t; //<-Initializes the string member
>
>
> Now we can also add explicit default constructors for all of the union
> members and get the brace initialization syntax back again.
>
> One potential ambiguity:
>
> union U {
> std::string s;
> std::string v;
> };
>
> Which one does U::U(std::string) initialize? Maybe it doesn't matter?
> Since they both occupy the same memory we could just say the first one, or
> which one is implementation defined. Maybe its a compiler error, but that
> could break legacy code.
>
> Finally, now we get to tagged initialization. With C tagged init syntax,
> everything works just fine.
>
> U u { .s = "hello" };
>
> With constructors with named arguments, maybe it doesn't work.
>
> U u(.s = "hello");
>
> How does the above know which single argument constructor to call? Deduce
> the types from the initializers and look at the names? I think this is a
> general conflict when combining overloading and named function parameters
> that needs to be resolved.
>
>
>
>>
>> Should there be a shortcut that allows us to get the per-element
>> constructors?
>>
>
> Not sure what you mean here?
>
>
>> By the way, if you write ~U() = default; the destructor is still deleted.
>>
>>
> This is fine. I don't think it ever makes sense to write a destructor for
> a union because you don't know which member to destruct. This probably
> should stay deleted.
>
>
>> --
>> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>>    Software Architect - Intel Open Source Technology Center
>>       PGP/GPG: 0x6EF45358; fingerprint:
>>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>>
>
>
> Ok, after all that my head hurts.
>

--

---
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+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_9_21739184.1402965909624
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">And one thing I got wrong, named function parameters won't=
 enable this syntax.<br><br>v.emplace_back(.y =3D 2);<br><br>I don't think =
this is actually possible. Unless variadic templates are enhanced somehow w=
ith yet another feature to derive names for their variadic arguments.<br><b=
r>On Monday, June 16, 2014 8:36:59 PM UTC-4, Matthew Fioravante wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><br>On Monday,=
 June 16, 2014 5:51:31 PM UTC-4, Thiago Macieira wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex">&gt; What we're essentially doing is adding a compiler =
generated default
<br>&gt; constructor which takes a set of arguments equal to the data membe=
rs. This
<br>&gt; does not make sense at all unless all data members are public.
<br>
<br>Correct, but that doesn't change brace initialisation. You can't do tha=
t for=20
<br>non-public members:
<br></blockquote><div><br>Actually now that I think about it that doesn't m=
ake sense. Braced initialization is not creating new constructors. Its just=
 another C compatible magic abomination which lets you initialize structs. =
For C compatibility, tagged initialization syntax should work the same way =
as braced initialization syntax, and Daryle's proposal seems to be providin=
g just that.<br><br>Now we are discussing something entirely different. Tha=
t is compiler generated default constructors for structs which have a param=
eter list matching the data members. In this case, initializing the data me=
mbers by name will depend on a named function argument proposal, either the=
 idea sketched earlier here or another implementation.<br><br>We already ge=
t this from C and Daryle's proposal:<br>struct S { int x; int y; };<br>1) S=
 s{1, 2};<br>2) S s{.y =3D 2};<br><br>Adding actual constructors to the mix=
, gives us these:<br>3) S s(1, 2);<br>4) S s(.y =3D 2); //Depends on a name=
d function arguments proposal<br><br>std::vector&lt;S&gt; s;<br>5) s.emplac=
e_back(1, 2);<br>6) s.emplace_back(.y =3D 2); //This would be nice<br><br>I=
 think the emplace_back() example (5) here is a real issue. We should be ab=
le to perfect forward the struct initialization syntax for both tagged and =
non-tagged braced initialization. Having an actual constructor for S genera=
ted by the compiler would allow perfect forwarding to work for (5) and also=
 give us (3) . Adding named function parameters on top of that would enable=
 (4) and (6).<br><br>By adding the compiler generated member constructor, w=
e get perfect forwarding to work here in emplace_back and other forwarding =
functions which I believe is a good thing. Now there is a complication wher=
e when you initialize a struct, sometimes you're doing this magic C brace t=
hing, and other times you're calling a constructor.<br><br>S s{1, 2}; //C b=
race init magic thing<br>S s(1, 2); //Constructor call<br>v.emplace_back(1,=
 2); //Constructor call<br><br>BIG QUESTION: <b>Does this difference actual=
ly mean anything in practice anywhere?</b> If it does that's another stupid=
 esoteric C++ rule that people have to learn. That's a big problem. I hate =
those with a passion and would really not like to introduce more.<br><br>So=
me solutions to this:<br>1) Do nothing. If the semantics are exactly the sa=
me, and only language lawyers need to know the difference then its probably=
 fine.<br>2) Change {} initialization to call the constructor. Actually thi=
s can be accomplished by simply removing the C brace initialization rules f=
rom the standard. The syntax would then "fall back" to just being a constru=
ctor call. For all purposes of C compatibility, the semantics would have to=
 be the same. This would also mean we don't need Daryle's proposal at all, =
because named function parameters would also give us the tagged brace initi=
alization syntax for free.<br><br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex">&gt;=20
<br>&gt; struct S {
<br>&gt; &nbsp; int x;
<br>&gt; &nbsp; int y;
<br>&gt; &nbsp; S(int x, int y) =3D default;
<br>&gt; }
<br>&gt; How do we "default" all of the lvalue/rvalue variations?
<br>
<br>Hmm... that's a good question. Maybe if you default the default constru=
ctor,=20
<br>it should just work. GCC, Clang and ICC appear to already work like tha=
t.
<br></blockquote><div><br>It looks like on gcc 4.9 you can still use brace =
and tagged initialization even if you delete the default constructor. Its o=
nly when you define another constructor that braced initialization gets dis=
abled. Was that an oversight in C++11? Tieing C compatible braced and tagge=
d initialization to the default constructor seems like a better idea than d=
epending on whether a user defined constructor was written. <br><br>If I de=
lete the default constructor, I should disable brace init as well. Removing=
 brace init in favor of implict constructors would fix this problem as well=
..<br><br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">&gt; What about =
inheritance? The below seems reasonable:
<br>&gt;=20
<br>&gt; struct A {
<br>&gt; &nbsp; int a;
<br>&gt; &nbsp; int b;
<br>&gt; };
<br>&gt;=20
<br>&gt; struct B : public A {
<br>&gt; &nbsp; int c;
<br>&gt; &nbsp; int d;
<br>&gt; };
<br>&gt;=20
<br>&gt; B b{ .a =3D 1, .b =3D 2, .c =3D3, .d =3D 4};
<br>
<br>This does not exist in C, so we're in new territory here. In C++98, B w=
asn't=20
<br>eligible for brace initialisation because it wasn't POD. With C++11, it=
's now=20
<br>trivial layout and trivially initialisable, but it's still not brace-
<br>initialisable.
<br>
<br>I don't see a need to change. You must provide a constructor if you wan=
t the=20
<br>above to work:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constexpr B(int a, int =
b, int c, int d) : A{a, b}, c{c}, d{d} {}
<br></blockquote><div><br>I suppose that's fair. If you want to compose str=
ucts you can just use containment instead of inheritance. Containment also =
avoids name clashes if you have multiple inheritance and 2 base classes wit=
h the same data member names.<br>&nbsp;</div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex">
<br>&gt; How about copy initialization?
<br>&gt;=20
<br>&gt; B b =3D { a. =3D1 , b =3D .2, .c =3D 3, .d =3D 4};
<br>
<br>Same rules as from pre-history: the copy constructor is elided and you =
just=20
<br>call the default constructor above. It needs to be supported for C99=20
<br>compatibility too.
<br>
<br>&gt; How about assignment?
<br>&gt;=20
<br>&gt; B b;
<br>&gt; b =3D { a. =3D 1, ... };
<br>
<br>This is a different one. It probably should not work as written. But th=
is=20
<br>should:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B b;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b =3D B{ .a =3D 1 };
<br></blockquote><div><br>Seems ok, if tagged initialization is not actuall=
y defining a new constructor and works like brace initialization.<br>&nbsp;=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex">&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;b =3D B(.a =3D 1);
<br></blockquote><div><br>This should fail to compile, unless we have these=
 implicit constructors and named constructor arguments. <br>&nbsp;</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">
<br>&gt; If the {} expression produces an anonymous struct, that means we n=
eed some
<br>&gt; kind of implicit conversion to B. How does this affect C compatibi=
lity?
<br>&gt;=20
<br>&gt; How about unions?
<br>
<br>You can initialise at most one element. Right now, for:
<br>
<br>union U { int i; double d; };
<br>
<br>The following works:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U u1 =3D {};
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U u2 =3D { 1 };
<br>
<br>But this doesn't:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U u3 =3D { 1.0 };
<br>due to narrowing of double to int, when trying to initialise U(int) [it=
 works=20
<br>in C++98 and in C, but produces possibly unexpected results]. This work=
s in=20
<br>C99:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;union U u4 =3D { .d =3D=
 1.0 };
<br>
&nbsp;</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">So we should all=
ow in C++ too. </blockquote><div><br>Pretty straightforward for the C tagge=
d syntax if that is to be adopted.<br><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex">So the rule for unions is that the default=20
<br>constructor is equivalent to one-argument constructors taking each of t=
he=20
<br>members, with the exact same access level, type and name.
<br>
<br>The interesting thing here will be dealing with C++11's unrestricted un=
ions:=20
<br>the constructor gets deleted by default if any of the members has a non=
-
<br>trivial constructor (e.g., add std::string s; to the union above). We c=
an=20
<br>bring them back:
<br>
<br>union U {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::string s;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constexpr U(int i) : i(=
i) {}
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U(std::string s) : s(s)=
 {}
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~U() {}
<br>};
<br></blockquote><div><br>Unions are an interesting case here.<br><br>I thi=
nk disabling the default constructor is somewhat misguided. It seems like a=
 way of promoting encapsulation within the union, that is making union more=
 like a class and more "safe". You can even add member functions to a union=
, which to me seems almost useless as you don't know which member is active=
.. <br><br>The problem is that its still very easy to access an uninitialize=
d object. You cannot encapsulate all of the initialized objects with a unio=
n alone because at minimum you need one more piece of external state, that =
is a tag to tell you which object is active. For that, you have to wrap the=
 union in a class if you want to protect it. Therefore, unions should be th=
ought of more like structs than classes. I wish the standard would stop try=
ing to protect us from ourselves here. If you are using union, you are poin=
ting the loaded gun at your foot and you know it so everyone should get out=
 of the way. The C++03 restrictions were arbitrary and extremely annoying. =
<br><br>The empty constructor is somewhat dangerous, because all it does is=
 leave the entire union in an undefined state. However it could be useful, =
if we enable the below:<br><br>union U {<br>int x =3D 2;<br>int y;<br>std::=
string s;<br>};<br><br>U u; //&lt;-default constructor U::U() will initiali=
zed x to 2, x is the active object.<br><br>union V {<br>int x =3D 2;<br>int=
 y =3D 3; //compiler error, as before. Multiple fields initialized.<br>};<b=
r><br>union T {<br>std::string s =3D {};<br>std::vector&lt;int&gt; v;<br>};=
<br><br>T t; //&lt;-Initializes the string member<br><br><br>Now we can als=
o add explicit default constructors for all of the union members and get th=
e brace initialization syntax back again.<br><br>One potential ambiguity:<b=
r><br>union U {<br>std::string s;<br>std::string v;<br>};<br><br>Which one =
does U::U(std::string) initialize? Maybe it doesn't matter? Since they both=
 occupy the same memory we could just say the first one, or which one is im=
plementation defined. Maybe its a compiler error, but that could break lega=
cy code.<br><br>Finally, now we get to tagged initialization. With C tagged=
 init syntax, everything works just fine.<br><br>U u { .s =3D "hello" };<br=
><br>With constructors with named arguments, maybe it doesn't work.<br><br>=
U u(.s =3D "hello"); <br><br>How does the above know which single argument =
constructor to call? Deduce the types from the initializers and look at the=
 names? I think this is a general conflict when combining overloading and n=
amed function parameters that needs to be resolved.<br><br>&nbsp;</div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex">
<br>Should there be a shortcut that allows us to get the per-element constr=
uctors?=20
<br></blockquote><div><br>Not sure what you mean here?<br>&nbsp;</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">By the way, if you write ~U() =3D defaul=
t; the destructor is still deleted.
<br>
<br></blockquote><div><br>This is fine. I don't think it ever makes sense t=
o write a destructor for a union because you don't know which member to des=
truct. This probably should stay deleted.<br>&nbsp;</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQjCNEswDUBNCNanbu7euhq=
Ln_62FW8ag';return true;" onclick=3D"this.href=3D'http://www.google.com/url=
?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQjCNEswDUBNC=
Nanbu7euhqLn_62FW8ag';return true;">macieira.info</a> - thiago (AT) <a href=
=3D"http://kde.org" target=3D"_blank" onmousedown=3D"this.href=3D'http://ww=
w.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQj=
CNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;" onclick=3D"this.href=3D'http:=
//www.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75=
AFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;">kde.org</a>
<br>&nbsp; &nbsp;Software Architect - Intel Open Source Technology Center
<br>&nbsp; &nbsp; &nbsp; PGP/GPG: 0x6EF45358; fingerprint:
<br>&nbsp; &nbsp; &nbsp; E067 918B B660 DBD1 105C &nbsp;966C 33F5 F005 6EF4=
 5358
<br></blockquote><div><br><br>Ok, after all that my head hurts. <br></div><=
/div></blockquote></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_9_21739184.1402965909624--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 16 Jun 2014 18:02:33 -0700
Raw View
Em seg 16 jun 2014, =E0s 17:36:58, Matthew Fioravante escreveu:
> Some solutions to this:
> 1) Do nothing. If the semantics are exactly the same, and only language=
=20
> lawyers need to know the difference then its probably fine.
> 2) Change {} initialization to call the constructor. Actually this can be=
=20
> accomplished by simply removing the C brace initialization rules from the=
=20
> standard. The syntax would then "fall back" to just being a constructor=
=20
> call. For all purposes of C compatibility, the semantics would have to be=
=20
> the same. This would also mean we don't need Daryle's proposal at all,=20
> because named function parameters would also give us the tagged brace=20
> initialization syntax for free.

I think they are basically the same right now and should remain so. But to=
=20
simplify the language rules, we may want to switch to #2.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@gmail.com>
Date: Tue, 17 Jun 2014 09:37:57 +0800
Raw View
--Apple-Mail=_2CE2B57D-ACCA-4155-B54E-0F708101C966
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On 2014-06-17, at 5:43 AM, corentin.schreiber@cea.fr wrote:

> Le lundi 16 juin 2014 21:18:52 UTC+2, Matthew Fioravante a =E9crit :
> That also implies adding support for C tagged structure initialization to=
 C++, which implies defining how it works with constructors. At first pass,=
 I'd say only enable the syntax for POD structs. This would need to be stud=
ied very carefully. I wouldn't be surprised if this was already brought up =
in the past, studied, and rejected for some reason. Does anyone have insigh=
t on that? Google doesn't appear to be helpful.
>=20
> A proposal has been written recently:
> https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IgDFqKjK=
lRs/CGARpDJy9JsJ=20
> I do not know what is the current status of that proposal though.

It would probably be better to make a clean start, based on review of discu=
ssions on this forum.

Note, I was advocating the designated initializer solution earlier in this =
thread but nobody seemed to care at the time. Anyone who's interested might=
 check those posts.

I'd also help draft such a proposal if someone wants a collaborator. Right =
now I'm hoping to attend the November meeting in Champaign, although it's n=
ot a guarantee and I might have a full plate with other proposals. However,=
 at this point a paper exploring the design space might be more appropriate=
 than an attempt at fully-baked wording, which reduces the burden of advoca=
cy. There are a number of issues and corner cases to check, and the committ=
ee needs to approve the "what" before the "how."

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_2CE2B57D-ACCA-4155-B54E-0F708101C966
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;06&ndash;17, at 5:43 AM, <a href=3D"mailto:corentin.schreiber@cea.fr"=
>corentin.schreiber@cea.fr</a> wrote:</div><br class=3D"Apple-interchange-n=
ewline"><blockquote type=3D"cite"><div dir=3D"ltr">Le lundi 16 juin 2014 21=
:18:52 UTC+2, Matthew Fioravante a =E9crit&nbsp;:<blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr">That also implies adding support for C =
tagged structure initialization to C++, which implies defining how it works=
 with constructors. At first pass, I'd say only enable the syntax for POD s=
tructs. This would need to be studied very carefully. I wouldn't be surpris=
ed if this was already brought up in the past, studied, and rejected for so=
me reason. Does anyone have insight on that? Google doesn't appear to be he=
lpful.</div></blockquote><div><br>A proposal has been written recently:<br>=
<a href=3D"https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals=
/IgDFqKjKlRs/CGARpDJy9JsJ">https://groups.google.com/a/isocpp.org/forum/#!m=
sg/std-proposals/IgDFqKjKlRs/CGARpDJy9JsJ</a> <br>I do not know what is the=
 current status of that proposal though.<br></div><mytubeelement data=3D"{&=
quot;bundle&quot;:{&quot;label_delimitor&quot;:&quot;:&quot;,&quot;percenta=
ge&quot;:&quot;%&quot;,&quot;smart_buffer&quot;:&quot;Smart Buffer&quot;,&q=
uot;start_playing_when_buffered&quot;:&quot;Start playing when buffered&quo=
t;,&quot;sound&quot;:&quot;Sound&quot;,&quot;desktop_notification&quot;:&qu=
ot;Desktop Notification&quot;,&quot;continuation_on_next_line&quot;:&quot;-=
&quot;,&quot;loop&quot;:&quot;Loop&quot;,&quot;only_notify&quot;:&quot;Only=
 Notify&quot;,&quot;estimated_time&quot;:&quot;Estimated Time&quot;,&quot;g=
lobal_preferences&quot;:&quot;Global Preferences&quot;,&quot;no_notificatio=
n_supported_on_your_browser&quot;:&quot;No notification style supported on =
your browser version&quot;,&quot;video_buffered&quot;:&quot;Video Buffered&=
quot;,&quot;buffered&quot;:&quot;Buffered&quot;,&quot;hyphen&quot;:&quot;-&=
quot;,&quot;buffered_message&quot;:&quot;The video has been buffered as req=
uested and is ready to play.&quot;,&quot;not_supported&quot;:&quot;Not Supp=
orted&quot;,&quot;on&quot;:&quot;On&quot;,&quot;off&quot;:&quot;Off&quot;,&=
quot;click_to_enable_for_this_site&quot;:&quot;Click to enable for this sit=
e&quot;,&quot;desktop_notification_denied&quot;:&quot;You have denied permi=
ssion for desktop notification for this site&quot;,&quot;notification_statu=
s_delimitor&quot;:&quot;;&quot;,&quot;error&quot;:&quot;Error&quot;,&quot;a=
dblock_interferance_message&quot;:&quot;Adblock (or similar extension) is k=
nown to interfere with SmartVideo. Please add this url to adblock whitelist=
..&quot;,&quot;calculating&quot;:&quot;Calculating&quot;,&quot;waiting&quot;=
:&quot;Waiting&quot;,&quot;will_start_buffering_when_initialized&quot;:&quo=
t;Will start buffering when initialized&quot;,&quot;will_start_playing_when=
_initialized&quot;:&quot;Will start playing when initialized&quot;,&quot;co=
mpleted&quot;:&quot;Completed&quot;,&quot;buffering_stalled&quot;:&quot;Buf=
fering is stalled. Will stop.&quot;,&quot;stopped&quot;:&quot;Stopped&quot;=
,&quot;hr&quot;:&quot;Hr&quot;,&quot;min&quot;:&quot;Min&quot;,&quot;sec&qu=
ot;:&quot;Sec&quot;,&quot;any_moment&quot;:&quot;Any Moment&quot;,&quot;pop=
up_donate_to&quot;:&quot;Donate to&quot;,&quot;extension_id&quot;:null},&qu=
ot;prefs&quot;:{&quot;desktopNotification&quot;:true,&quot;soundNotificatio=
n&quot;:false,&quot;logLevel&quot;:0,&quot;enable&quot;:true,&quot;loop&quo=
t;:false,&quot;hidePopup&quot;:true,&quot;autoPlay&quot;:false,&quot;autoBu=
ffer&quot;:false,&quot;autoPlayOnBuffer&quot;:false,&quot;autoPlayOnBufferP=
ercentage&quot;:42,&quot;autoPlayOnSmartBuffer&quot;:true,&quot;quality&quo=
t;:&quot;default&quot;,&quot;fshd&quot;:false,&quot;onlyNotification&quot;:=
true,&quot;enableFullScreen&quot;:true,&quot;saveBandwidth&quot;:false,&quo=
t;hideAnnotations&quot;:true,&quot;turnOffPagedBuffering&quot;:true}}" even=
t=3D"preferencesUpdated" id=3D"myTubeRelayElementToPage"></mytubeelement><m=
ytubeelement data=3D"{&quot;loadBundle&quot;:true}" event=3D"relayPrefs" id=
=3D"myTubeRelayElementToTab"></mytubeelement></div></blockquote><br></div><=
div>It would probably be better to make a clean start, based on review of d=
iscussions on this forum.</div><br><div>Note, I was advocating the designat=
ed initializer solution earlier in this thread but nobody seemed to care at=
 the time. Anyone who&rsquo;s interested might check those posts.</div><div=
><br></div><div>I&rsquo;d also help draft such a proposal if someone wants =
a collaborator. Right now I&rsquo;m hoping to attend the November meeting i=
n Champaign, although it&rsquo;s not a guarantee and I might have a full pl=
ate with other proposals. However, at this point a paper exploring the desi=
gn space might be more appropriate than an attempt at fully-baked wording, =
which reduces the burden of advocacy. There are a number of issues and corn=
er cases to check, and the committee needs to approve the &ldquo;what&rdquo=
; before the &ldquo;how.&rdquo;</div><div><br></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_2CE2B57D-ACCA-4155-B54E-0F708101C966--

.