Topic: Strong typedefs: a reprise (discussion wanted)


Author: svalorzen@gmail.com
Date: Tue, 19 Jun 2018 10:18:40 -0700 (PDT)
Raw View
------=_Part_25304_1486544414.1529428720172
Content-Type: multipart/alternative;
 boundary="----=_Part_25305_1822575584.1529428720174"

------=_Part_25305_1822575584.1529428720174
Content-Type: text/plain; charset="UTF-8"

Around 18 months ago I submitted here a proposal for strong typedefs. I have
received feedback about it, and I've worked on it a bit more. However, by
talking to people at the Rapperswil meeting I have realized that people have
different expectations for strong typedefs as me.

I have some specific questions about strong typedefs features which I'd
like to
open for discussion, use-cases, counter-examples, etc. so that we can start
to
hone in onto the semantics that strong typedefs should have in C++. If the
discussion is useful, I'd love to come up with additional questions and do
this
again until I have a proposal that satisfies all requirements.

Use cases that I know exists are centered on:
- StrongId types: primitive types that have certain operations disabled on
  them.
- GUI applications: integer values with intermediate float math, stop
certain
  types of integers from being passed at compile time.
- String manipulation: disabling operations between encrypted and
unencrypted
  strings.
- Scientific applications: enable modifying internals without breaking
  interfaces. # I am personally here

That said, here are some questions which I would like you to reflect and
comment upon. I have put my comments there already, but please let me know
what
you think. I also don't have direct use-cases for some of these questions,
so
if you know of any please let me know.

I'm going to use the placeholder syntax of

struct A = B {};

to indicate a strong typedef from B to A in order to discuss things. I'm
also
assuming that strong typedefs and inheritance are mutually exclusive (it is
not
possible to do both at the same time).

*# (1) SHOULD WE ALLOW STRONG TYPEDEFS OF NON-PRIMITIVE TYPES? #*

If non-primitive types are not included, use cases for strong typing
existing
classes like strings, vectors, etc are not possible.

If allowed, this would significantly impact the design of the feature, as
non-primitive types can interact in much more complicated ways than
primitive
types (see below questions).

*# (2) BY DEFAULT SHOULD WE KEEP EVERYTHING THE SAME? #*

This seems a simple enough decision to make, but it does have consequences
and if answered affirmatively does create some problems. We'll see them
below,
and finally in (9) we discuss a possible alternative.

Most opinions I've gathered on this tend to agree that a simple strong
typedef
should be pretty much equivalent to a copy of the original class, so:

struct A {
    int x;
    void foo() {}
};

struct B = A {};

/* Equivalent to
struct B {
    int x;
    void foo() {}
}; */

*# (3) IS STRONG TYPEDEF (OF STRONG TYPEDEF) OF INHERITING CLASS INHERITING
FROM SAME BASES? #*

Assuming (1) is answered positively, and given the following:

    struct A {};
    struct B : A {};
    struct C = B {};

Does C inherit from A?

This question has consequences in whether it is possible to extend an
existing
class without introducing an inheritance dependency (see (4) and (6)).

If a strong typedef of an inheriting class does not inherit from the same
bases, there would be no other way to produce the same effect, unless
additional syntax is introduced, for example:

    struct C = B : A {};

*# (4) CAN I ADD ATTRIBUTES TO A CLASS? #*

If attributes cannot be added, then there would be no way to extend a class
without the extension being a child of the original. This follows from
question
(2), if it is answered in the affirmative. This is bad since it would bypass
most of the usefulness of strong typing.

At the same time, this might bring some problems when trying to build a
strong
typedefs. Consider:

    struct A {
        int x;
        A foo() { return {1}; }
    };

    struct X {
        X(int) {} // No default constructor
    };

    struct B = A {
        B() : x(1) {}
        X x;
    };

    B b; b.foo(); // ??? we can't convert foo() to construct a B anymore

Note that the implementation of the original A foo() might not be visible to
the writer of B.

*# (5) CAN I REMOVE/REDEFINE ATTRIBUTES FROM A CLASS? #*

If attributes can be removed/redefined, the functions carried over from the
original class would all break as the layout of the new class has changed.
This might not be obvious to detect as definitions might be in other
translation units. Consider:

    struct A {
        int x;
        void foo() { ++x; }
    };

    struct B {
        int x = delete;
    };

    B b; b.foo(); // ???

This might be hidden by keeping the deleted members in the class and just
preventing their usage, but it would probably become weird very soon.

Changing access might be doable, although inheritance can already do that.

*# (6) CAN I ADD FUNCTIONS TO A CLASS? #*

As for attributes, if methods cannot be added, then there is no way to do so
without the extension being a child of the original. Again this follows from
(2), if answered affirmatively.

I haven't found any particular drawbacks here yet though.

*# (7) CAN I REMOVE/REDEFINE FUNCTIONS FROM A CLASS? #*

Redefinition and removal of member functions would also incur in similar
problems as removal of member attributes, as other member functions might be
using them. This could be partially fixed by hiding removed functions, but
still using them under the hood. However, this still might result in weird
situations. Consider (all in placeholder syntax):

struct A {
    int x;
    A foo() { return bar(); }
    A bar() { return {1}; }
};

struct B = A {
   A::foo() = default; // Carry foo from A, becomes B foo();
   A::bar() = delete; // Remove B bar() from interface completely.
};

struct C = B {
    B::foo() = default; // Carry foo from B, becomes C foo();
};

// User code below
struct D = C {
    C::foo() = default; // Carry foo from C, becomes D foo();
    D(int) {}
};

D d{4};
d.foo(); // Error, A::bar() cannot construct D anymore, but D user never
knew about bar()

This might happen with very deeply nested classes, so that the original
wouldn't really be visible or known to the user. Another problem is how to
detect it at compile time, if the implementation can be in another
translation
unit? This might also get compounded if we allowed adding and removing
member
attributes.

*# (8) SHOULD NON-MEMBER FUNCTIONS CARRY OVER? #*

This is one of the hot topics of strong typedefs. Whether there should be a
mechanism to carry over non-member functions to strong typedefs, or not.

While that can be a matter of preference, I just wanted here to make the
point
that it is very easy to have something similar to what we have done above no
matter what is chosen:

struct A {
    int x;
    A foo();
};

// A.cpp
A bar() { return {1}; }
A A::foo() { return bar(); }

// Other files
struct B = A {
   A::foo() = default; // Carry foo from A, becomes B foo();
   A::bar() = delete; // Remove B bar() from interface completely.
};
struct C = B {
    B::foo() = default; // Carry foo from B, becomes C foo();
};

// User code below
struct D = C {
    C::foo() = default; // Carry foo from C, becomes D foo();
    D(int) {}
};

D d{4};
d.foo(); // What to do about non-member A bar(), invisible from the user?


*# (9) BARRING FUNCTIONS THAT RETURN THE ORIGINAL CLASS BY VALUE? #*

It has occurred to me that most of these problems only happen when we edit
the
original interface (destructively for functions, additively for members)
and we
call a member function that should return the class by value.

I haven't found a way to break the editing process in another way, so maybe
simply automatically disabling these functions once member functions are
removed or non-default-constructible attributes are added could suffice. I
haven't explored deeply in this direction yet.


--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c7beea3b-69f7-4fc5-9df8-5f667c09049a%40isocpp.org.

------=_Part_25305_1822575584.1529428720174
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Around 18 months ago I submitted here a proposal for stron=
g typedefs. I have<br>received feedback about it, and I&#39;ve worked on it=
 a bit more. However, by<br>talking to people at the Rapperswil meeting I h=
ave realized that people have<br>different expectations for strong typedefs=
 as me.<br><br>I have some specific questions about strong typedefs feature=
s which I&#39;d like to<br>open for discussion, use-cases, counter-examples=
, etc. so that we can start to<br>hone in onto the semantics that strong ty=
pedefs should have in C++. If the<br>discussion is useful, I&#39;d love to =
come up with additional questions and do this<br>again until I have a propo=
sal that satisfies all requirements.<br><br>Use cases that I know exists ar=
e centered on:<br>- StrongId types: primitive types that have certain opera=
tions disabled on<br>=C2=A0 them.<br>- GUI applications: integer values wit=
h intermediate float math, stop certain<br>=C2=A0 types of integers from be=
ing passed at compile time.<br>- String manipulation: disabling operations =
between encrypted and unencrypted<br>=C2=A0 strings.<br>- Scientific applic=
ations: enable modifying internals without breaking<br>=C2=A0 interfaces. #=
 I am personally here<br><br>That said, here are some questions which I wou=
ld like you to reflect and<br>comment upon. I have put my comments there al=
ready, but please let me know what<br>you think. I also don&#39;t have dire=
ct use-cases for some of these questions, so<br>if you know of any please l=
et me know.<br><br>I&#39;m going to use the placeholder syntax of<br><br><d=
iv style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; overflow-wrap: break-word;=
" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> A </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> B </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{};</span></div></code></div><br>to=
 indicate a strong typedef from B to A in order to discuss things. I&#39;m =
also<br>assuming that strong typedefs and inheritance are mutually exclusiv=
e (it is not<br>possible to do both at the same time).<br><b><br># (1) SHOU=
LD WE ALLOW STRONG TYPEDEFS OF NON-PRIMITIVE TYPES? #</b><br><br>If non-pri=
mitive types are not included, use cases for strong typing existing<br>clas=
ses like strings, vectors, etc are not possible.<br><br>If allowed, this wo=
uld significantly impact the design of the feature, as<br>non-primitive typ=
es can interact in much more complicated ways than primitive<br>types (see =
below questions).<br><b><br># (2) BY DEFAULT SHOULD WE KEEP EVERYTHING THE =
SAME? #</b><br><br><div>This seems a simple enough decision to make, but it=
 does have consequences <br></div><div>and if answered affirmatively does c=
reate some problems. We&#39;ll see them below,</div><div> and finally in (9=
) we discuss a possible alternative.</div><br>Most opinions I&#39;ve gather=
ed on this tend to agree that a simple strong typedef<br>should be pretty m=
uch equivalent to a copy of the original class, so:<br><br><div style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pre=
ttyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> A </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> B </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> A </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">/* Equivalent to<br>struct B {<br>=C2=A0 =C2=A0 int x;<br>=
=C2=A0 =C2=A0 void foo() {}<br>}; */</span></div></code></div><br><b># (3) =
IS STRONG TYPEDEF (OF STRONG TYPEDEF) OF INHERITING CLASS INHERITING FROM S=
AME BASES? #</b><br><br>Assuming (1) is answered positively, and given the =
following:<br><br><div style=3D"background-color: rgb(250, 250, 250); borde=
r-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; overfl=
ow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-=
prettify">=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> A </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 B </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> A </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> C </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> B </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{};</span></div></code></div><br>Does C inher=
it from A?<br><br>This question has consequences in whether it is possible =
to extend an existing<br>class without introducing an inheritance dependenc=
y (see (4) and (6)).<br><br>If a strong typedef of an inheriting class does=
 not inherit from the same<br>bases, there would be no other way to produce=
 the same effect, unless<br>additional syntax is introduced, for example:<b=
r><br><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb=
(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: bre=
ak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"s=
ubprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 C </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> B </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> A </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{};</span></div></code></div><br><b=
># (4) CAN I ADD ATTRIBUTES TO A CLASS? #</b><br><br>If attributes cannot b=
e added, then there would be no way to extend a class<br>without the extens=
ion being a child of the original. This follows from question<br>(2), if it=
 is answered in the affirmative. This is bad since it would bypass<br>most =
of the usefulness of strong typing.<br><br>At the same time, this might bri=
ng some problems when trying to build a strong<br>typedefs. Consider:<br><b=
r><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187=
, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break-w=
ord;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">=C2=A0=
 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">st=
ruct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> A </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 A foo</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #066;" clas=
s=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 X </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 X</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">// No default constructor</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> B </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> A </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 B</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 X x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=
=A0 =C2=A0 B b</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">// ??? we can&#39;t convert foo() to constru=
ct a B anymore</span></div></code></div><br>Note that the implementation of=
 the original A foo() might not be visible to<br>the writer of B.<br><br><b=
># (5) CAN I REMOVE/REDEFINE ATTRIBUTES FROM A CLASS? #</b><br><br>If attri=
butes can be removed/redefined, the functions carried over from the<br>orig=
inal class would all break as the layout of the new class has changed.<br>T=
his might not be obvious to detect as definitions might be in other<br>tran=
slation units. Consider:<br><br><div style=3D"background-color: rgb(250, 25=
0, 250); border-color: rgb(187, 187, 187); border-style: solid; border-widt=
h: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> A </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">++</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">x</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> B </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>delete</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=
=A0 =C2=A0 B b</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">// ???</span></div></code></div><br>This mig=
ht be hidden by keeping the deleted members in the class and just<br>preven=
ting their usage, but it would probably become weird very soon.<br><br>Chan=
ging access might be doable, although inheritance can already do that.<br><=
br><b># (6) CAN I ADD FUNCTIONS TO A CLASS? #</b><br><br>As for attributes,=
 if methods cannot be added, then there is no way to do so<br>without the e=
xtension being a child of the original. Again this follows from<br>(2), if =
answered affirmatively.<br><br>I haven&#39;t found any particular drawbacks=
 here yet though.<br><br><b># (7) CAN I REMOVE/REDEFINE FUNCTIONS FROM A CL=
ASS? #</b><br><br>Redefinition and removal of member functions would also i=
ncur in similar<br>problems as removal of member attributes, as other membe=
r functions might be<br>using them. This could be partially fixed by hiding=
 removed functions, but<br>still using them under the hood. However, this s=
till might result in weird<br>situations. Consider (all in placeholder synt=
ax):<br><br><div style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wra=
p: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 A </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 A foo</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> bar</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
 =C2=A0 A bar</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D=
"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> B </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> A </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0A</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">default</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">// Carry foo from A, becomes B foo();</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0A=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">bar</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">delete</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Re=
move B bar() from interface completely.</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> C </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> B <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 B<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">foo</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">default</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Ca=
rry foo from B, becomes C foo();</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">// User code below</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> D </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> C </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 C</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">default</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Car=
ry foo from C, becomes D foo();</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>=C2=A0 =C2=A0 D</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{}</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br><br>D d</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">4</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>d</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #800;" class=3D"styled-by-prettify">// Error, A::=
bar() cannot construct D anymore, but D user never knew about bar()</span><=
/div></code></div><br>This might happen with very deeply nested classes, so=
 that the original<br>wouldn&#39;t really be visible or known to the user. =
Another problem is how to<br>detect it at compile time, if the implementati=
on can be in another translation<br>unit? This might also get compounded if=
 we allowed adding and removing member<br>attributes.<br><br><b># (8) SHOUL=
D NON-MEMBER FUNCTIONS CARRY OVER? #</b><br><br>This is one of the hot topi=
cs of strong typedefs. Whether there should be a<br>mechanism to carry over=
 non-member functions to strong typedefs, or not.<br><br>While that can be =
a matter of preference, I just wanted here to make the point<br>that it is =
very easy to have something similar to what we have done above no<br>matter=
 what is chosen:<br><br><div style=3D"background-color: rgb(250, 250, 250);=
 border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprin=
t"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> A </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 A =
foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// A.cpp</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>A bar</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>A A</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// Other files</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> B </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> A </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0A</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">default</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Car=
ry foo from A, becomes B foo();</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>=C2=A0 =C2=A0A</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">bar</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">delete</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #8=
00;" class=3D"styled-by-prettify">// Remove B bar() from interface complete=
ly.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> C </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> B </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 B</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">default</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">// Carry foo from B, becomes C foo();</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// User code below</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> D </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> C </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 C</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">default</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// Carry foo from C, becomes D foo();</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 D</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{}</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br><br>D d</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #066;" class=3D"styled-by-prettify">4=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>d</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">foo</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">// What to do about non-member A bar(), invisible from =
the user?</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br><br></span></div></code></div><br><b># (9) BARRING FUNCTIONS THAT RETURN=
 THE ORIGINAL CLASS BY VALUE? #</b><br><br>It has occurred to me that most =
of these problems only happen when we edit the<br>original interface (destr=
uctively for functions, additively for members) and we<br>call a member fun=
ction that should return the class by value.<br><br>I haven&#39;t found a w=
ay to break the editing process in another way, so maybe<br>simply automati=
cally disabling these functions once member functions are<br>removed or non=
-default-constructible attributes are added could suffice. I<br>haven&#39;t=
 explored deeply in this direction yet.<br><br><br></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c7beea3b-69f7-4fc5-9df8-5f667c09049a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c7beea3b-69f7-4fc5-9df8-5f667c09049a=
%40isocpp.org</a>.<br />

------=_Part_25305_1822575584.1529428720174--

------=_Part_25304_1486544414.1529428720172--

.


Author: Jens Maurer <Jens.Maurer@gmx.net>
Date: Tue, 19 Jun 2018 19:30:33 +0200
Raw View
On 06/19/2018 07:18 PM, svalorzen@gmail.com wrote:
> Around 18 months ago I submitted here a proposal for strong typedefs. I have
> received feedback about it, and I've worked on it a bit more. However, by
> talking to people at the Rapperswil meeting I have realized that people have
> different expectations for strong typedefs as me.
>
> I have some specific questions about strong typedefs features which I'd like to
> open for discussion, use-cases, counter-examples, etc. so that we can start to
> hone in onto the semantics that strong typedefs should have in C++. If the
> discussion is useful, I'd love to come up with additional questions and do this
> again until I have a proposal that satisfies all requirements.
>
> Use cases that I know exists are centered on:
> - StrongId types: primitive types that have certain operations disabled on
>   them.

It seems to me this use-case has been addressed by scoped enums with explicit
underlying type, at least for the actual "id" case.

> - GUI applications: integer values with intermediate float math, stop certain
>   types of integers from being passed at compile time.
> - String manipulation: disabling operations between encrypted and unencrypted
>   strings.
> - Scientific applications: enable modifying internals without breaking
>   interfaces. # I am personally here
>
> That said, here are some questions which I would like you to reflect and
> comment upon.

These all seem to apply to strong typedefs for classes.

I'd like to see more (specific) use-cases why those would be useful,
or rather, why derivation and member composition isn't good enough and
what kind of bang-for-the-complexity I'd get with your variant of
strong typedefs.

Jens

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5B293DB9.4000007%40gmx.net.

.


Author: Peter Sommerlad <peter.sommerlad@hsr.ch>
Date: Tue, 19 Jun 2018 19:44:10 +0200
Raw View
--Apple-Mail-DB754A3C-A97E-4C56-90E6-ABD742C28457
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi,

With C++17/20 aggregate initialization rules and structured bindings one ca=
n create strong types by having the wrapped type as a member. I am playing =
around with a single header library for exactly just that and can share the=
 incomplete prototype (directly email me, since i might not see the mailing=
 list reply due to my mental bandwidth). I think this might be better a lib=
rary-only approach than separate syntax. And because of the different use c=
ases, i believe different libraries, even when not standardized, can serve =
them better than a language solution that fits neither well enough.

There have been other proposals for strong typing, ie inheriting from non-c=
lass types, i remember one from Walter Brown that did not make it through e=
volution working group as far as i remember.=20

Regards
Peter

Sent from Peter Sommerlad's iPad
+41 79 432 23 32

> On 19 Jun 2018, at 19:18, "svalorzen@gmail.com" <svalorzen@gmail.com> wro=
te:
>=20
> Around 18 months ago I submitted here a proposal for strong typedefs. I h=
ave
> received feedback about it, and I've worked on it a bit more. However, by
> talking to people at the Rapperswil meeting I have realized that people h=
ave
> different expectations for strong typedefs as me.
>=20
> I have some specific questions about strong typedefs features which I'd l=
ike to
> open for discussion, use-cases, counter-examples, etc. so that we can sta=
rt to
> hone in onto the semantics that strong typedefs should have in C++. If th=
e
> discussion is useful, I'd love to come up with additional questions and d=
o this
> again until I have a proposal that satisfies all requirements.
>=20
> Use cases that I know exists are centered on:
> - StrongId types: primitive types that have certain operations disabled o=
n
>   them.
> - GUI applications: integer values with intermediate float math, stop cer=
tain
>   types of integers from being passed at compile time.
> - String manipulation: disabling operations between encrypted and unencry=
pted
>   strings.
> - Scientific applications: enable modifying internals without breaking
>   interfaces. # I am personally here
>=20
> That said, here are some questions which I would like you to reflect and
> comment upon. I have put my comments there already, but please let me kno=
w what
> you think. I also don't have direct use-cases for some of these questions=
, so
> if you know of any please let me know.
>=20
> I'm going to use the placeholder syntax of
>=20
> struct A =3D B {};
>=20
> to indicate a strong typedef from B to A in order to discuss things. I'm =
also
> assuming that strong typedefs and inheritance are mutually exclusive (it =
is not
> possible to do both at the same time).
>=20
> # (1) SHOULD WE ALLOW STRONG TYPEDEFS OF NON-PRIMITIVE TYPES? #
>=20
> If non-primitive types are not included, use cases for strong typing exis=
ting
> classes like strings, vectors, etc are not possible.
>=20
> If allowed, this would significantly impact the design of the feature, as
> non-primitive types can interact in much more complicated ways than primi=
tive
> types (see below questions).
>=20
> # (2) BY DEFAULT SHOULD WE KEEP EVERYTHING THE SAME? #
>=20
> This seems a simple enough decision to make, but it does have consequence=
s=20
> and if answered affirmatively does create some problems. We'll see them b=
elow,
> and finally in (9) we discuss a possible alternative.
>=20
> Most opinions I've gathered on this tend to agree that a simple strong ty=
pedef
> should be pretty much equivalent to a copy of the original class, so:
>=20
> struct A {
>     int x;
>     void foo() {}
> };
>=20
> struct B =3D A {};
>=20
> /* Equivalent to
> struct B {
>     int x;
>     void foo() {}
> }; */
>=20
> # (3) IS STRONG TYPEDEF (OF STRONG TYPEDEF) OF INHERITING CLASS INHERITIN=
G FROM SAME BASES? #
>=20
> Assuming (1) is answered positively, and given the following:
>=20
>     struct A {};
>     struct B : A {};
>     struct C =3D B {};
>=20
> Does C inherit from A?
>=20
> This question has consequences in whether it is possible to extend an exi=
sting
> class without introducing an inheritance dependency (see (4) and (6)).
>=20
> If a strong typedef of an inheriting class does not inherit from the same
> bases, there would be no other way to produce the same effect, unless
> additional syntax is introduced, for example:
>=20
>     struct C =3D B : A {};
>=20
> # (4) CAN I ADD ATTRIBUTES TO A CLASS? #
>=20
> If attributes cannot be added, then there would be no way to extend a cla=
ss
> without the extension being a child of the original. This follows from qu=
estion
> (2), if it is answered in the affirmative. This is bad since it would byp=
ass
> most of the usefulness of strong typing.
>=20
> At the same time, this might bring some problems when trying to build a s=
trong
> typedefs. Consider:
>=20
>     struct A {
>         int x;
>         A foo() { return {1}; }
>     };
>=20
>     struct X {
>         X(int) {} // No default constructor
>     };
>=20
>     struct B =3D A {
>         B() : x(1) {}
>         X x;
>     };
>=20
>     B b; b.foo(); // ??? we can't convert foo() to construct a B anymore
>=20
> Note that the implementation of the original A foo() might not be visible=
 to
> the writer of B.
>=20
> # (5) CAN I REMOVE/REDEFINE ATTRIBUTES FROM A CLASS? #
>=20
> If attributes can be removed/redefined, the functions carried over from t=
he
> original class would all break as the layout of the new class has changed=
..
> This might not be obvious to detect as definitions might be in other
> translation units. Consider:
>=20
>     struct A {
>         int x;
>         void foo() { ++x; }
>     };
>=20
>     struct B {
>         int x =3D delete;
>     };
>=20
>     B b; b.foo(); // ???
>=20
> This might be hidden by keeping the deleted members in the class and just
> preventing their usage, but it would probably become weird very soon.
>=20
> Changing access might be doable, although inheritance can already do that=
..
>=20
> # (6) CAN I ADD FUNCTIONS TO A CLASS? #
>=20
> As for attributes, if methods cannot be added, then there is no way to do=
 so
> without the extension being a child of the original. Again this follows f=
rom
> (2), if answered affirmatively.
>=20
> I haven't found any particular drawbacks here yet though.
>=20
> # (7) CAN I REMOVE/REDEFINE FUNCTIONS FROM A CLASS? #
>=20
> Redefinition and removal of member functions would also incur in similar
> problems as removal of member attributes, as other member functions might=
 be
> using them. This could be partially fixed by hiding removed functions, bu=
t
> still using them under the hood. However, this still might result in weir=
d
> situations. Consider (all in placeholder syntax):
>=20
> struct A {
>     int x;
>     A foo() { return bar(); }
>     A bar() { return {1}; }
> };
>=20
> struct B =3D A {
>    A::foo() =3D default; // Carry foo from A, becomes B foo();
>    A::bar() =3D delete; // Remove B bar() from interface completely.
> };
>=20
> struct C =3D B {
>     B::foo() =3D default; // Carry foo from B, becomes C foo();
> };
>=20
> // User code below
> struct D =3D C {
>     C::foo() =3D default; // Carry foo from C, becomes D foo();
>     D(int) {}
> };
>=20
> D d{4};
> d.foo(); // Error, A::bar() cannot construct D anymore, but D user never =
knew about bar()
>=20
> This might happen with very deeply nested classes, so that the original
> wouldn't really be visible or known to the user. Another problem is how t=
o
> detect it at compile time, if the implementation can be in another transl=
ation
> unit? This might also get compounded if we allowed adding and removing me=
mber
> attributes.
>=20
> # (8) SHOULD NON-MEMBER FUNCTIONS CARRY OVER? #
>=20
> This is one of the hot topics of strong typedefs. Whether there should be=
 a
> mechanism to carry over non-member functions to strong typedefs, or not.
>=20
> While that can be a matter of preference, I just wanted here to make the =
point
> that it is very easy to have something similar to what we have done above=
 no
> matter what is chosen:
>=20
> struct A {
>     int x;
>     A foo();
> };
>=20
> // A.cpp
> A bar() { return {1}; }
> A A::foo() { return bar(); }
>=20
> // Other files
> struct B =3D A {
>    A::foo() =3D default; // Carry foo from A, becomes B foo();
>    A::bar() =3D delete; // Remove B bar() from interface completely.
> };
> struct C =3D B {
>     B::foo() =3D default; // Carry foo from B, becomes C foo();
> };
>=20
> // User code below
> struct D =3D C {
>     C::foo() =3D default; // Carry foo from C, becomes D foo();
>     D(int) {}
> };
>=20
> D d{4};
> d.foo(); // What to do about non-member A bar(), invisible from the user?
>=20
>=20
> # (9) BARRING FUNCTIONS THAT RETURN THE ORIGINAL CLASS BY VALUE? #
>=20
> It has occurred to me that most of these problems only happen when we edi=
t the
> original interface (destructively for functions, additively for members) =
and we
> call a member function that should return the class by value.
>=20
> I haven't found a way to break the editing process in another way, so may=
be
> simply automatically disabling these functions once member functions are
> removed or non-default-constructible attributes are added could suffice. =
I
> haven't explored deeply in this direction yet.
>=20
>=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=
 email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/c7beea3b-69f7-4fc5-9df8-5f667c09049a%40isocpp.=
org.

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/F7442253-3FFA-4A3D-BD7C-CABBB46B9F1D%40hsr.ch.

--Apple-Mail-DB754A3C-A97E-4C56-90E6-ABD742C28457
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto">Hi,<div><br></div><div>With C++17/20 ag=
gregate initialization rules and structured bindings one can create strong =
types by having the wrapped type as a member. I am playing around with a si=
ngle header library for exactly just that and can share the incomplete prot=
otype (directly email me, since i might not see the mailing list reply due =
to my mental bandwidth). I think this might be better a library-only approa=
ch than separate syntax. And because of the different use cases, i believe =
different libraries, even when not standardized, can serve them better than=
 a language solution that fits neither well enough.</div><div><br></div><di=
v>There have been other proposals for strong typing, ie inheriting from non=
-class types, i remember one from Walter Brown that did not make it through=
 evolution working group as far as i remember.&nbsp;</div><div><br></div><d=
iv>Regards</div><div>Peter</div><div><br><div id=3D"AppleMailSignature">Sen=
t from Peter Sommerlad's<span class=3D"Apple-style-span" style=3D"-webkit-t=
ap-highlight-color: rgba(26, 26, 26, 0.296875); -webkit-composition-fill-co=
lor: rgba(175, 192, 227, 0.230469); -webkit-composition-frame-color: rgba(7=
7, 128, 180, 0.230469); ">&nbsp;iPad</span><div><span class=3D"Apple-style-=
span" style=3D"-webkit-tap-highlight-color: rgba(26, 26, 26, 0.296875); -we=
bkit-composition-fill-color: rgba(175, 192, 227, 0.230469); -webkit-composi=
tion-frame-color: rgba(77, 128, 180, 0.230469); ">+41 79 432 23 32</span></=
div></div><div><br>On 19 Jun 2018, at 19:18, "<a href=3D"mailto:svalorzen@g=
mail.com">svalorzen@gmail.com</a>" &lt;<a href=3D"mailto:svalorzen@gmail.co=
m">svalorzen@gmail.com</a>&gt; wrote:<br><br></div><blockquote type=3D"cite=
"><div><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dut=
f-8"><div dir=3D"ltr">Around 18 months ago I submitted here a proposal for =
strong typedefs. I have<br>received feedback about it, and I've worked on i=
t a bit more. However, by<br>talking to people at the Rapperswil meeting I =
have realized that people have<br>different expectations for strong typedef=
s as me.<br><br>I have some specific questions about strong typedefs featur=
es which I'd like to<br>open for discussion, use-cases, counter-examples, e=
tc. so that we can start to<br>hone in onto the semantics that strong typed=
efs should have in C++. If the<br>discussion is useful, I'd love to come up=
 with additional questions and do this<br>again until I have a proposal tha=
t satisfies all requirements.<br><br>Use cases that I know exists are cente=
red on:<br>- StrongId types: primitive types that have certain operations d=
isabled on<br>&nbsp; them.<br>- GUI applications: integer values with inter=
mediate float math, stop certain<br>&nbsp; types of integers from being pas=
sed at compile time.<br>- String manipulation: disabling operations between=
 encrypted and unencrypted<br>&nbsp; strings.<br>- Scientific applications:=
 enable modifying internals without breaking<br>&nbsp; interfaces. # I am p=
ersonally here<br><br>That said, here are some questions which I would like=
 you to reflect and<br>comment upon. I have put my comments there already, =
but please let me know what<br>you think. I also don't have direct use-case=
s for some of these questions, so<br>if you know of any please let me know.=
<br><br>I'm going to use the placeholder syntax of<br><br><div style=3D"bac=
kground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border=
-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pret=
typrint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> A </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> B </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{};</span></div></code></div><br>to indicate a st=
rong typedef from B to A in order to discuss things. I'm also<br>assuming t=
hat strong typedefs and inheritance are mutually exclusive (it is not<br>po=
ssible to do both at the same time).<br><b><br># (1) SHOULD WE ALLOW STRONG=
 TYPEDEFS OF NON-PRIMITIVE TYPES? #</b><br><br>If non-primitive types are n=
ot included, use cases for strong typing existing<br>classes like strings, =
vectors, etc are not possible.<br><br>If allowed, this would significantly =
impact the design of the feature, as<br>non-primitive types can interact in=
 much more complicated ways than primitive<br>types (see below questions).<=
br><b><br># (2) BY DEFAULT SHOULD WE KEEP EVERYTHING THE SAME? #</b><br><br=
><div>This seems a simple enough decision to make, but it does have consequ=
ences <br></div><div>and if answered affirmatively does create some problem=
s. We'll see them below,</div><div> and finally in (9) we discuss a possibl=
e alternative.</div><br>Most opinions I've gathered on this tend to agree t=
hat a simple strong typedef<br>should be pretty much equivalent to a copy o=
f the original class, so:<br><br><div style=3D"background-color: rgb(250, 2=
50, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wid=
th: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> A </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; =
&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">voi=
d</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{}</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> B </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> A </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{};</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">/* Equivalent t=
o<br>struct B {<br>&nbsp; &nbsp; int x;<br>&nbsp; &nbsp; void foo() {}<br>}=
; */</span></div></code></div><br><b># (3) IS STRONG TYPEDEF (OF STRONG TYP=
EDEF) OF INHERITING CLASS INHERITING FROM SAME BASES? #</b><br><br>Assuming=
 (1) is answered positively, and given the following:<br><br><div style=3D"=
background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bor=
der-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"p=
rettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> A </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> B </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> A </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> C </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> B </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
};</span></div></code></div><br>Does C inherit from A?<br><br>This question=
 has consequences in whether it is possible to extend an existing<br>class =
without introducing an inheritance dependency (see (4) and (6)).<br><br>If =
a strong typedef of an inheriting class does not inherit from the same<br>b=
ases, there would be no other way to produce the same effect, unless<br>add=
itional syntax is introduced, for example:<br><br><div style=3D"background-=
color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: =
solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> C </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> B </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> A </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{};</span></div></code></div><br><b># (4) CAN I ADD ATTRIBUTES TO A=
 CLASS? #</b><br><br>If attributes cannot be added, then there would be no =
way to extend a class<br>without the extension being a child of the origina=
l. This follows from question<br>(2), if it is answered in the affirmative.=
 This is bad since it would bypass<br>most of the usefulness of strong typi=
ng.<br><br>At the same time, this might bring some problems when trying to =
build a strong<br>typedefs. Consider:<br><br><div style=3D"background-color=
: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid=
; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> A </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; A foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br><br>&nbsp; &nbsp; </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> X </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; X</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{}</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
 No default constructor</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> B </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> A </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp=
; &nbsp; &nbsp; &nbsp; B</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{}</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; X x</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br><br>&nbsp; &nbsp; B b</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// ???=
 we can't convert foo() to construct a B anymore</span></div></code></div><=
br>Note that the implementation of the original A foo() might not be visibl=
e to<br>the writer of B.<br><br><b># (5) CAN I REMOVE/REDEFINE ATTRIBUTES F=
ROM A CLASS? #</b><br><br>If attributes can be removed/redefined, the funct=
ions carried over from the<br>original class would all break as the layout =
of the new class has changed.<br>This might not be obvious to detect as def=
initions might be in other<br>translation units. Consider:<br><br><div styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> A </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">++</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; &nbsp; </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> B </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">delete</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br><br>&nbsp; &nbsp; B b</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">// ???</span></d=
iv></code></div><br>This might be hidden by keeping the deleted members in =
the class and just<br>preventing their usage, but it would probably become =
weird very soon.<br><br>Changing access might be doable, although inheritan=
ce can already do that.<br><br><b># (6) CAN I ADD FUNCTIONS TO A CLASS? #</=
b><br><br>As for attributes, if methods cannot be added, then there is no w=
ay to do so<br>without the extension being a child of the original. Again t=
his follows from<br>(2), if answered affirmatively.<br><br>I haven't found =
any particular drawbacks here yet though.<br><br><b># (7) CAN I REMOVE/REDE=
FINE FUNCTIONS FROM A CLASS? #</b><br><br>Redefinition and removal of membe=
r functions would also incur in similar<br>problems as removal of member at=
tributes, as other member functions might be<br>using them. This could be p=
artially fixed by hiding removed functions, but<br>still using them under t=
he hood. However, this still might result in weird<br>situations. Consider =
(all in placeholder syntax):<br><br><div style=3D"background-color: rgb(250=
, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-=
width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> A </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; &nbsp; A foo</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>&nbsp; &nbsp; A bar</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><b=
r></span><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> B </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> A </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp;A</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">default=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// Carry foo from A, becomes=
 B foo();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>&nbsp; &nbsp;A</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">b=
ar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">delete</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">// Remove B bar() from interface completely.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> C </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> B </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>&nbsp; &nbsp; B</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">fo=
o</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">default</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">// Carry foo from B, becomes C foo();</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// User code below</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> D </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> C </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; &nbsp; C</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">foo</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">default</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// Carry foo from C, becomes D foo();</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; D</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{}</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br=
>D d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #066;" class=3D"styled-by-prettify">4</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>d</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">// Error, A::bar() cannot construct D anymore, but D user never kne=
w about bar()</span></div></code></div><br>This might happen with very deep=
ly nested classes, so that the original<br>wouldn't really be visible or kn=
own to the user. Another problem is how to<br>detect it at compile time, if=
 the implementation can be in another translation<br>unit? This might also =
get compounded if we allowed adding and removing member<br>attributes.<br><=
br><b># (8) SHOULD NON-MEMBER FUNCTIONS CARRY OVER? #</b><br><br>This is on=
e of the hot topics of strong typedefs. Whether there should be a<br>mechan=
ism to carry over non-member functions to strong typedefs, or not.<br><br>W=
hile that can be a matter of preference, I just wanted here to make the poi=
nt<br>that it is very easy to have something similar to what we have done a=
bove no<br>matter what is chosen:<br><br><div style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> A </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>&nbsp; &nbsp; A foo</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// A.cpp</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>A bar</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>A A</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> bar</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// Other files</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> B </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> A </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
&nbsp; &nbsp;A</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">foo<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">default</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// Carry foo from A, becomes B foo();</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp;A</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">bar</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">d=
elete</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">// Remove B bar() from =
interface completely.</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> C </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> B </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; B</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">default=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// Carry foo from B, becomes=
 C foo();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// User code belo=
w</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> D </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> C </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>&nbsp; &nbsp; C</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">default</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// Carry foo from C, becomes D foo=
();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nb=
sp; &nbsp; D</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{}</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br><br>D d</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">4</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">foo</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// What to do about non-member A bar(=
), invisible from the user?</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span></div></code></div><br><b># (9) BARRING FUN=
CTIONS THAT RETURN THE ORIGINAL CLASS BY VALUE? #</b><br><br>It has occurre=
d to me that most of these problems only happen when we edit the<br>origina=
l interface (destructively for functions, additively for members) and we<br=
>call a member function that should return the class by value.<br><br>I hav=
en't found a way to break the editing process in another way, so maybe<br>s=
imply automatically disabling these functions once member functions are<br>=
removed or non-default-constructible attributes are added could suffice. I<=
br>haven't explored deeply in this direction yet.<br><br><br></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c7beea3b-69f7-4fc5-9df8-5f667c09049a%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter">https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/c7beea3b-69f7-4fc5-9df8-5f667c09=
049a%40isocpp.org</a>.<br>
</div></blockquote></div></body></html>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/F7442253-3FFA-4A3D-BD7C-CABBB46B9F1D%=
40hsr.ch?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/F7442253-3FFA-4A3D-BD7C-CABBB46B9F1D%40h=
sr.ch</a>.<br />

--Apple-Mail-DB754A3C-A97E-4C56-90E6-ABD742C28457--

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Tue, 19 Jun 2018 11:00:42 -0700 (PDT)
Raw View
------=_Part_25076_298076358.1529431242452
Content-Type: multipart/alternative;
 boundary="----=_Part_25077_1193365403.1529431242452"

------=_Part_25077_1193365403.1529431242452
Content-Type: text/plain; charset="UTF-8"



On Tuesday, June 19, 2018 at 12:44:23 PM UTC-5, PeterSommerlad wrote:
>
> Hi,
>
> With C++17/20 aggregate initialization rules and structured bindings one
> can create strong types by having the wrapped type as a member. I am
> playing around with a single header library for exactly just that and can
> share the incomplete prototype (directly email me, since i might not see
> the mailing list reply due to my mental bandwidth). I think this might be
> better a library-only approach than separate syntax. And because of the
> different use cases, i believe different libraries, even when not
> standardized, can serve them better than a language solution that fits
> neither well enough.
>
> There have been other proposals for strong typing, ie inheriting from
> non-class types, i remember one from Walter Brown that did not make it
> through evolution working group as far as i remember.
>
> Regards
> Peter
>


That would be this one:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0109r0.pdf

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-b59b-274f91208196%40isocpp.org.

------=_Part_25077_1193365403.1529431242452
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, June 19, 2018 at 12:44:23 PM UTC-5, Pe=
terSommerlad wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"auto">Hi,<div><br></div><div>With C++17/20 aggregate initialization rules =
and structured bindings one can create strong types by having the wrapped t=
ype as a member. I am playing around with a single header library for exact=
ly just that and can share the incomplete prototype (directly email me, sin=
ce i might not see the mailing list reply due to my mental bandwidth). I th=
ink this might be better a library-only approach than separate syntax. And =
because of the different use cases, i believe different libraries, even whe=
n not standardized, can serve them better than a language solution that fit=
s neither well enough.</div><div><br></div><div>There have been other propo=
sals for strong typing, ie inheriting from non-class types, i remember one =
from Walter Brown that did not make it through evolution working group as f=
ar as i remember.=C2=A0</div><div><br></div><div>Regards</div><div>Peter</d=
iv></div></blockquote><div><br></div><div><br></div><div>That would be this=
 one: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0109r0.pdf</=
div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-b59b-274f91208196%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-b59b-274f91208196=
%40isocpp.org</a>.<br />

------=_Part_25077_1193365403.1529431242452--

------=_Part_25076_298076358.1529431242452--

.


Author: Eugenio Bargiacchi <svalorzen@gmail.com>
Date: Tue, 19 Jun 2018 22:19:39 +0200
Raw View
--000000000000d725c2056f0466f2
Content-Type: text/plain; charset="UTF-8"

>
> It seems to me this use-case has been addressed by scoped enums with
> explicit
> underlying type, at least for the actual "id" case.


That may be, although they are very clunky for that purpose. You still have
to cast every time you want to assign something to them, which is not
super-pretty.

These all seem to apply to strong typedefs for classes.
>
> I'd like to see more (specific) use-cases why those would be useful,
> or rather, why derivation and member composition isn't good enough and
> what kind of bang-for-the-complexity I'd get with your variant of
> strong typedefs.
>

Indeed, strong typedefs for classes would really be useful and so I'm
taking them into consideration, but so do previous paper such as P0109, as
they explicitly talk about the encrypted strings use case, for example.

There are many use-cases for strong typedefs, and they have been
consistently spelled out in all papers about them that we have had,
including P0109 by Walter E. Brown which goes not only through the various
use-cases, but also has quotes from authors of tentative libraries that
tried to implement similar functionality.

All in all, it is clear to everybody that strong typedefs are simply
syntactical sugar, as anything they do can be done with lots of elbow
grease and lots of copy pasted code. Still I think having them would be
worth it, as do many other people. Derivation does not work as it enforces
an 'is-an' relationship between classes, and allows for implicit casting
between classes, which proponents of strong typing explicitly don't want
(unless it is explicitly allowed). Wrapping does not work since it requires
forwarding lots of functions by hand. Template tags do not work since they
cannot be applied to every single class in existence. The list goes on.

My personal use-case is that I maintain a library for research-level
software, and I want people to have access and manipulate internals (even
private) since they might need it for something. But I don't want to make
everything public either. In my case a strong typedef would simply allow
them to clone my original classes and mess with the internals in a
controlled manner, without resorting to copy-pasting half of my library. As
I said, I don't have all the use-cases in the world, but I think that in
general there a relatively strong consensus that if they were somehow
incorporated in the language, people would use them - also shown by the
number of tentative implementations there are.

Note that I haven't proposed anything here. I was just asking questions,
and I'm simply curious to know what people think the answers are, since
opinions about this topic are very varied. I do have a partial
implementation of my proposal, which is actually done by a simple
search-and-replace script in python (so actual complexity = low), but I'm
not looking to get feedback on that here.

On Tue, Jun 19, 2018 at 8:00 PM, Barry Revzin <barry.revzin@gmail.com>
wrote:

>
>
> On Tuesday, June 19, 2018 at 12:44:23 PM UTC-5, PeterSommerlad wrote:
>>
>> Hi,
>>
>> With C++17/20 aggregate initialization rules and structured bindings one
>> can create strong types by having the wrapped type as a member. I am
>> playing around with a single header library for exactly just that and can
>> share the incomplete prototype (directly email me, since i might not see
>> the mailing list reply due to my mental bandwidth). I think this might be
>> better a library-only approach than separate syntax. And because of the
>> different use cases, i believe different libraries, even when not
>> standardized, can serve them better than a language solution that fits
>> neither well enough.
>>
>> There have been other proposals for strong typing, ie inheriting from
>> non-class types, i remember one from Walter Brown that did not make it
>> through evolution working group as far as i remember.
>>
>> Regards
>> Peter
>>
>
>
> That would be this one: http://www.open-std.org/jtc1/
> sc22/wg21/docs/papers/2015/p0109r0.pdf
>
> --
> 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/SORgghABBic/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-
> b59b-274f91208196%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-b59b-274f91208196%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2BuP8nJXY5%3Du_P_Nt6x1RFsmCfC_Uhgzdb17qAByatn%3DSQ%40mail.gmail.com.

--000000000000d725c2056f0466f2
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It seems=
 to me this use-case has been addressed by scoped enums with explicit<br>un=
derlying type, at least for the actual &quot;id&quot; case.</blockquote><di=
v><br></div><div>That may be, although they are very clunky for that purpos=
e. You still have to cast every time you want to assign something to them, =
which is not super-pretty.</div><div><br></div><div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,=
204,204);padding-left:1ex">These all seem to apply to strong typedefs for c=
lasses.<br><br>
I&#39;d like to see more (specific) use-cases why those would be useful,<br=
>
or rather, why derivation and member composition isn&#39;t good enough and<=
br>
what kind of bang-for-the-complexity I&#39;d get with your variant of<br>
strong typedefs.<br></blockquote>

 </div><div><br></div><div>Indeed, strong typedefs for classes would really=
 be useful and so I&#39;m taking them into consideration, but so do previou=
s paper such as P0109, as they explicitly talk about the encrypted strings =
use case, for example.<br></div><div><br></div><div>There are many use-case=
s for strong typedefs, and they have been consistently spelled out in all p=
apers about them that we have had, including P0109 by Walter E. Brown which=
 goes not only through the various use-cases, but also has quotes from auth=
ors of tentative libraries that tried to implement similar functionality.<b=
r></div><div><br></div><div>All in all, it is clear to everybody that stron=
g typedefs are simply syntactical sugar, as anything they do can be done wi=
th lots of elbow grease and lots of copy pasted code. Still I think having =
them would be worth it, as do many other people. Derivation does not work a=
s it enforces an &#39;is-an&#39; relationship between classes, and allows f=
or implicit casting between classes, which proponents of strong typing expl=
icitly don&#39;t want (unless it is explicitly allowed). Wrapping does not =
work since it requires forwarding lots of functions by hand. Template tags =
do not work since they cannot be applied to every single class in existence=
.. The list goes on.</div><div><br></div><div>My personal use-case is that I=
 maintain a library for research-level software, and I want people to have =
access and manipulate internals (even private) since they might need it for=
 something. But I don&#39;t want to make everything public either. In my ca=
se a strong typedef would simply allow them to clone my original classes an=
d mess with the internals in a controlled manner, without resorting to copy=
-pasting half of my library. As I said, I don&#39;t have all the use-cases =
in the world, but I think that in general there a relatively strong consens=
us that if they were somehow incorporated in the language, people would use=
 them - also shown by the number of tentative implementations there are.<br=
></div><div><br></div><div>Note that I haven&#39;t proposed anything here. =
I was just asking questions, and I&#39;m simply curious to know what people=
 think the answers are, since opinions about this topic are very varied. I =
do have a partial implementation of my proposal, which is actually done by =
a simple search-and-replace script in python (so actual complexity =3D low)=
, but I&#39;m not looking to get feedback on that here.<br></div></div><div=
 class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Tue, Jun 19, 2018 =
at 8:00 PM, Barry Revzin <span dir=3D"ltr">&lt;<a href=3D"mailto:barry.revz=
in@gmail.com" target=3D"_blank">barry.revzin@gmail.com</a>&gt;</span> wrote=
:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D""><br><=
br>On Tuesday, June 19, 2018 at 12:44:23 PM UTC-5, PeterSommerlad wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"auto">Hi,<div><br></div><d=
iv>With C++17/20 aggregate initialization rules and structured bindings one=
 can create strong types by having the wrapped type as a member. I am playi=
ng around with a single header library for exactly just that and can share =
the incomplete prototype (directly email me, since i might not see the mail=
ing list reply due to my mental bandwidth). I think this might be better a =
library-only approach than separate syntax. And because of the different us=
e cases, i believe different libraries, even when not standardized, can ser=
ve them better than a language solution that fits neither well enough.</div=
><div><br></div><div>There have been other proposals for strong typing, ie =
inheriting from non-class types, i remember one from Walter Brown that did =
not make it through evolution working group as far as i remember.=C2=A0</di=
v><div><br></div><div>Regards</div><div>Peter</div></div></blockquote><div>=
<br></div><div><br></div></span><div>That would be this one: <a href=3D"htt=
p://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0109r0.pdf" target=3D=
"_blank">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2015/<wbr>=
p0109r0.pdf</a></div></div><span class=3D"">

<p></p>

-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/SORgghABBic/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/<wbr>isocpp.org/d/topic/std-<wbr>proposals/S=
ORgghABBic/<wbr>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-b59b-274f91208196%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/d488=
6f2c-a061-43c0-<wbr>b59b-274f91208196%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2BuP8nJXY5%3Du_P_Nt6x1RFsmCf=
C_Uhgzdb17qAByatn%3DSQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%=
2BuP8nJXY5%3Du_P_Nt6x1RFsmCfC_Uhgzdb17qAByatn%3DSQ%40mail.gmail.com</a>.<br=
 />

--000000000000d725c2056f0466f2--

.


Author: Eugenio Bargiacchi <svalorzen@gmail.com>
Date: Tue, 19 Jun 2018 22:21:19 +0200
Raw View
--000000000000cbebe7056f046c57
Content-Type: text/plain; charset="UTF-8"

>
> With C++17/20 aggregate initialization rules and structured bindings one
> can create strong types by having the wrapped type as a member. I am
> playing around with a single header library for exactly just that and can
> share the incomplete prototype (directly email me, since i might not see
> the mailing list reply due to my mental bandwidth). I think this might be
> better a library-only approach than separate syntax. And because of the
> different use cases, i believe different libraries, even when not
> standardized, can serve them better than a language solution that fits
> neither well enough.
>

I'm sending you an email now, if it works I'd be definitely happy to take
advantage of it.

There have been other proposals for strong typing, ie inheriting from
> non-class types, i remember one from Walter Brown that did not make it
> through evolution working group as far as i remember.
>

I know of it, and I've actually talked with Walter about it. He has been
trying to get strong typedefs in C++ for quite a long time now, and he also
has some pretty strong use cases to boot.

On Tue, Jun 19, 2018 at 10:19 PM, Eugenio Bargiacchi <svalorzen@gmail.com>
wrote:

> It seems to me this use-case has been addressed by scoped enums with
>> explicit
>> underlying type, at least for the actual "id" case.
>
>
> That may be, although they are very clunky for that purpose. You still
> have to cast every time you want to assign something to them, which is not
> super-pretty.
>
> These all seem to apply to strong typedefs for classes.
>>
>> I'd like to see more (specific) use-cases why those would be useful,
>> or rather, why derivation and member composition isn't good enough and
>> what kind of bang-for-the-complexity I'd get with your variant of
>> strong typedefs.
>>
>
> Indeed, strong typedefs for classes would really be useful and so I'm
> taking them into consideration, but so do previous paper such as P0109, as
> they explicitly talk about the encrypted strings use case, for example.
>
> There are many use-cases for strong typedefs, and they have been
> consistently spelled out in all papers about them that we have had,
> including P0109 by Walter E. Brown which goes not only through the various
> use-cases, but also has quotes from authors of tentative libraries that
> tried to implement similar functionality.
>
> All in all, it is clear to everybody that strong typedefs are simply
> syntactical sugar, as anything they do can be done with lots of elbow
> grease and lots of copy pasted code. Still I think having them would be
> worth it, as do many other people. Derivation does not work as it enforces
> an 'is-an' relationship between classes, and allows for implicit casting
> between classes, which proponents of strong typing explicitly don't want
> (unless it is explicitly allowed). Wrapping does not work since it requires
> forwarding lots of functions by hand. Template tags do not work since they
> cannot be applied to every single class in existence. The list goes on.
>
> My personal use-case is that I maintain a library for research-level
> software, and I want people to have access and manipulate internals (even
> private) since they might need it for something. But I don't want to make
> everything public either. In my case a strong typedef would simply allow
> them to clone my original classes and mess with the internals in a
> controlled manner, without resorting to copy-pasting half of my library. As
> I said, I don't have all the use-cases in the world, but I think that in
> general there a relatively strong consensus that if they were somehow
> incorporated in the language, people would use them - also shown by the
> number of tentative implementations there are.
>
> Note that I haven't proposed anything here. I was just asking questions,
> and I'm simply curious to know what people think the answers are, since
> opinions about this topic are very varied. I do have a partial
> implementation of my proposal, which is actually done by a simple
> search-and-replace script in python (so actual complexity = low), but I'm
> not looking to get feedback on that here.
>
> On Tue, Jun 19, 2018 at 8:00 PM, Barry Revzin <barry.revzin@gmail.com>
> wrote:
>
>>
>>
>> On Tuesday, June 19, 2018 at 12:44:23 PM UTC-5, PeterSommerlad wrote:
>>>
>>> Hi,
>>>
>>> With C++17/20 aggregate initialization rules and structured bindings one
>>> can create strong types by having the wrapped type as a member. I am
>>> playing around with a single header library for exactly just that and can
>>> share the incomplete prototype (directly email me, since i might not see
>>> the mailing list reply due to my mental bandwidth). I think this might be
>>> better a library-only approach than separate syntax. And because of the
>>> different use cases, i believe different libraries, even when not
>>> standardized, can serve them better than a language solution that fits
>>> neither well enough.
>>>
>>> There have been other proposals for strong typing, ie inheriting from
>>> non-class types, i remember one from Walter Brown that did not make it
>>> through evolution working group as far as i remember.
>>>
>>> Regards
>>> Peter
>>>
>>
>>
>> That would be this one: http://www.open-std.org/jtc1/s
>> c22/wg21/docs/papers/2015/p0109r0.pdf
>>
>> --
>> 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/is
>> ocpp.org/d/topic/std-proposals/SORgghABBic/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> To view this discussion on the web visit https://groups.google.com/a/is
>> ocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-b59b-
>> 274f91208196%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-b59b-274f91208196%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
>
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2Bush7bKV7PWvn7EaKEkocwLa1reR4900x91fLgrxYv3vQ%40mail.gmail.com.

--000000000000cbebe7056f046c57
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>Wit=
h C++17/20 aggregate initialization rules and structured=20
bindings one can create strong types by having the wrapped type as a=20
member. I am playing around with a single header library for exactly=20
just that and can share the incomplete prototype (directly email me,=20
since i might not see the mailing list reply due to my mental=20
bandwidth). I think this might be better a library-only approach than=20
separate syntax. And because of the different use cases, i believe=20
different libraries, even when not standardized, can serve them better=20
than a language solution that fits neither well enough.</div></blockquote><=
div><br></div><div>I&#39;m sending you an email now, if it works I&#39;d be=
 definitely happy to take advantage of it.<br></div><div><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px=
 solid rgb(204,204,204);padding-left:1ex"><div>There
 have been other proposals for strong typing, ie inheriting from=20
non-class types, i remember one from Walter Brown that did not make it=20
through evolution working group as far as i remember.=C2=A0</div></blockquo=
te><div><br></div><div>I know of it, and I&#39;ve actually talked with Walt=
er about it. He has been trying to get strong typedefs in C++ for quite a l=
ong time now, and he also has some pretty strong use cases to boot.<br></di=
v></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Tue, J=
un 19, 2018 at 10:19 PM, Eugenio Bargiacchi <span dir=3D"ltr">&lt;<a href=
=3D"mailto:svalorzen@gmail.com" target=3D"_blank">svalorzen@gmail.com</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span c=
lass=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It seems to me =
this use-case has been addressed by scoped enums with explicit<br>underlyin=
g type, at least for the actual &quot;id&quot; case.</blockquote><div><br><=
/div></span><div>That may be, although they are very clunky for that purpos=
e. You still have to cast every time you want to assign something to them, =
which is not super-pretty.</div><span class=3D""><div><br></div><div><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1=
px solid rgb(204,204,204);padding-left:1ex">These all seem to apply to stro=
ng typedefs for classes.<br><br>
I&#39;d like to see more (specific) use-cases why those would be useful,<br=
>
or rather, why derivation and member composition isn&#39;t good enough and<=
br>
what kind of bang-for-the-complexity I&#39;d get with your variant of<br>
strong typedefs.<br></blockquote>

 </div><div><br></div></span><div>Indeed, strong typedefs for classes would=
 really be useful and so I&#39;m taking them into consideration, but so do =
previous paper such as P0109, as they explicitly talk about the encrypted s=
trings use case, for example.<br></div><div><br></div><div>There are many u=
se-cases for strong typedefs, and they have been consistently spelled out i=
n all papers about them that we have had, including P0109 by Walter E. Brow=
n which goes not only through the various use-cases, but also has quotes fr=
om authors of tentative libraries that tried to implement similar functiona=
lity.<br></div><div><br></div><div>All in all, it is clear to everybody tha=
t strong typedefs are simply syntactical sugar, as anything they do can be =
done with lots of elbow grease and lots of copy pasted code. Still I think =
having them would be worth it, as do many other people. Derivation does not=
 work as it enforces an &#39;is-an&#39; relationship between classes, and a=
llows for implicit casting between classes, which proponents of strong typi=
ng explicitly don&#39;t want (unless it is explicitly allowed). Wrapping do=
es not work since it requires forwarding lots of functions by hand. Templat=
e tags do not work since they cannot be applied to every single class in ex=
istence. The list goes on.</div><div><br></div><div>My personal use-case is=
 that I maintain a library for research-level software, and I want people t=
o have access and manipulate internals (even private) since they might need=
 it for something. But I don&#39;t want to make everything public either. I=
n my case a strong typedef would simply allow them to clone my original cla=
sses and mess with the internals in a controlled manner, without resorting =
to copy-pasting half of my library. As I said, I don&#39;t have all the use=
-cases in the world, but I think that in general there a relatively strong =
consensus that if they were somehow incorporated in the language, people wo=
uld use them - also shown by the number of tentative implementations there =
are.<br></div><div><br></div><div>Note that I haven&#39;t proposed anything=
 here. I was just asking questions, and I&#39;m simply curious to know what=
 people think the answers are, since opinions about this topic are very var=
ied. I do have a partial implementation of my proposal, which is actually d=
one by a simple search-and-replace script in python (so actual complexity =
=3D low), but I&#39;m not looking to get feedback on that here.<br></div></=
div><div class=3D"HOEnZb"><div class=3D"h5"><div class=3D"gmail_extra"><br>=
<div class=3D"gmail_quote">On Tue, Jun 19, 2018 at 8:00 PM, Barry Revzin <s=
pan dir=3D"ltr">&lt;<a href=3D"mailto:barry.revzin@gmail.com" target=3D"_bl=
ank">barry.revzin@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><span><br><br>On Tuesday, June 19, 2018 at 12:44:=
23 PM UTC-5, PeterSommerlad wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"auto">Hi,<div><br></div><div>With C++17/20 aggregate initializ=
ation rules and structured bindings one can create strong types by having t=
he wrapped type as a member. I am playing around with a single header libra=
ry for exactly just that and can share the incomplete prototype (directly e=
mail me, since i might not see the mailing list reply due to my mental band=
width). I think this might be better a library-only approach than separate =
syntax. And because of the different use cases, i believe different librari=
es, even when not standardized, can serve them better than a language solut=
ion that fits neither well enough.</div><div><br></div><div>There have been=
 other proposals for strong typing, ie inheriting from non-class types, i r=
emember one from Walter Brown that did not make it through evolution workin=
g group as far as i remember.=C2=A0</div><div><br></div><div>Regards</div><=
div>Peter</div></div></blockquote><div><br></div><div><br></div></span><div=
>That would be this one: <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/=
docs/papers/2015/p0109r0.pdf" target=3D"_blank">http://www.open-std.org/jtc=
1/s<wbr>c22/wg21/docs/papers/2015/p010<wbr>9r0.pdf</a></div></div><span>

<p></p>

-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/SORgghABBic/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/is<wbr>ocpp.org/d/topic/std-proposals<wbr>/S=
ORgghABBic/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isoc<wbr>pp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d4886f2c-a061-43c0-b59b-274f91208196%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/is<wbr>ocpp.org/d/msgid/std-proposals<wbr>/d488=
6f2c-a061-43c0-b59b-<wbr>274f91208196%40isocpp.org</a>.<br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2Bush7bKV7PWvn7EaKEkocwLa1re=
R4900x91fLgrxYv3vQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2Bus=
h7bKV7PWvn7EaKEkocwLa1reR4900x91fLgrxYv3vQ%40mail.gmail.com</a>.<br />

--000000000000cbebe7056f046c57--

.