220 30149 <CAHfn=+tEbHpzdtK40qS_tVUPfPyKnOft-ZXOTMTDezPDzS3fAw@mail.gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Eugenio Bargiacchi <svalorzen@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: A strong typedef syntax idea
Date: Sun, 1 Jan 2017 18:26:16 +0100
Lines: 3406
Approved: news@gmane.org
Message-ID: <CAHfn=+tEbHpzdtK40qS_tVUPfPyKnOft-ZXOTMTDezPDzS3fAw@mail.gmail.com>
References: <fd8eda2b-182f-4e32-8fda-c7f728e22fa2@isocpp.org>
 <9574d1c1-b3ff-b9ae-ceee-908a2b983278@wanadoo.fr> <CAHfn=+t0MkFNY4h=crQWvh=JT2nHt5k_LWnO=SzgGkL2Q=_bSw@mail.gmail.com>
 <f4a57116-c65b-94f4-51f2-e5cf8b4ff3ca@wanadoo.fr> <CAHfn=+tVBKZOMtpURNBDCEJijFL_J5s+ROrLwJfkRgGyWzZMgg@mail.gmail.com>
 <ef8190c7-f46f-cf76-7e45-2114a84eae27@wanadoo.fr>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=94eb2c03c7908d1bfd05450bbbd4
X-Trace: blaine.gmane.org 1483291590 13819 195.159.176.226 (1 Jan 2017 17:26:30 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 1 Jan 2017 17:26:30 +0000 (UTC)
To: "ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCWJHLVBTMARBOXXUTBQKGQEE3IMUDA@isocpp.org Sun Jan 01 18:26:20 2017
Return-path: <std-proposals+bncBCWJHLVBTMARBOXXUTBQKGQEE3IMUDA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-oi0-f70.google.com ([209.85.218.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCWJHLVBTMARBOXXUTBQKGQEE3IMUDA@isocpp.org>)
	id 1cNjtf-00022B-Ib
	for gclcip-std-proposals@m.gmane.org; Sun, 01 Jan 2017 18:26:16 +0100
Original-Received: by mail-oi0-f70.google.com with SMTP id 3sf548076465oih.5
        for <gclcip-std-proposals@m.gmane.org>; Sun, 01 Jan 2017 09:26:19 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:in-reply-to:references:from:date:message-id:subject:to
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=udL9ZzSSdP2l5I1+xz+0Nkf/QortiaFx/r0SxTugCc4=;
        b=AMJ1IngAc6BVTiNcOgcDyOzllXr/gwWa+H867viqMUYi5cXqiwnZsZQn9hIfv4HYsh
         mFlbQJoZRjHsVByVC+kvBu60Yv/+b44qP7ek2ygh4iwT1kaGbnKqmUEKj8UNX4v/Y6da
         I2ATDJ04DRn2tzrjJSGOlydUSGjwBFrLr7IqnD6qh6FvhC/wFwo8JQkk/UrqI41qjZ1F
         o0HkXHW4aihO4XwZzzKXAZYyI5MUIRAqSz8Zcb577XfN0nw3Dx9zmltAOH3tjLZVJwcW
         lPrFvvIADtXZ+ZRCQpSAYnH/9yRZv1mJZyhCBXLkZhvwI4KW7x9s5gjBt3UH6Luz/VVg
         i8Jw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:mime-version:in-reply-to:references:from:date
         :message-id:subject:to:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=udL9ZzSSdP2l5I1+xz+0Nkf/QortiaFx/r0SxTugCc4=;
        b=NytQ+xhFOg/bC3UtDgORlajZNimQ88aZ+FbEUPMXWVEkmqfoVwgJSFtAkrWbBCbGfe
         s/e7k7xVQZFvjhqEAONQ1s72XvrpKMY4ogGNRuv66ClbwsNm/2QSfu29qofS3eZIfvSY
         Snz33EqtVsZhLCw/S0oxXP7OKHeYRf6wjxmEKYfZzlGz7kDEO83iLkpVwTClNLTVs2j8
         PlUhJ1n5RJMA2Qjq4XDheWoOwxXPKd7xRKJ9ycjtTJ5XPKtUhHT684RoNZiDeqJMe6AD
         bZq750Ve4J6tb7vp9Tc5S4q1Mnw1DWC55+i+2K8AWhiZemnUvPb/ssR0RI0oPm9kULCt
         mxIg==
X-Gm-Message-State: AIkVDXI1oixYXmXf5Nl3ZUWWpc8b58Tx/0nAXOUHFlXMZgPOr8HinYyEHyHMLsAd9tXZfw==
X-Received: by 10.157.19.78 with SMTP id q14mr13668504otq.2.1483291579154;
        Sun, 01 Jan 2017 09:26:19 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.58.38 with SMTP id j35ls3197201otc.17.gmail; Sun, 01 Jan
 2017 09:26:18 -0800 (PST)
X-Received: by 10.176.90.193 with SMTP id x1mr42104157uae.0.1483291578094;
        Sun, 01 Jan 2017 09:26:18 -0800 (PST)
Original-Received: from mail-ua0-x22f.google.com (mail-ua0-x22f.google.com. [2607:f8b0:400c:c08::22f])
        by mx.google.com with ESMTPS id 203si15678107vkm.202.2017.01.01.09.26.17
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Sun, 01 Jan 2017 09:26:18 -0800 (PST)
Received-SPF: pass (google.com: domain of svalorzen@gmail.com designates 2607:f8b0:400c:c08::22f as permitted sender) client-ip=2607:f8b0:400c:c08::22f;
Original-Received: by mail-ua0-x22f.google.com with SMTP id 88so282681725uaq.3
        for <std-proposals@isocpp.org>; Sun, 01 Jan 2017 09:26:17 -0800 (PST)
X-Received: by 10.159.35.232 with SMTP id 95mr25252334uao.5.1483291577095;
 Sun, 01 Jan 2017 09:26:17 -0800 (PST)
Original-Received: by 10.31.227.133 with HTTP; Sun, 1 Jan 2017 09:26:16 -0800 (PST)
In-Reply-To: <ef8190c7-f46f-cf76-7e45-2114a84eae27@wanadoo.fr>
X-Original-Sender: svalorzen@gmail.com
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@gmail.com;       spf=pass (google.com: domain of
 svalorzen@gmail.com designates 2607:f8b0:400c:c08::22f as permitted sender)
 smtp.mailfrom=svalorzen@gmail.com;       dmarc=pass (p=NONE dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:30149
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/30149>

--94eb2c03c7908d1bfd05450bbbd4
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Dear Vicente,

Eugenio, please, preserve some additional context in your responses.
>

Sorry, I'll try to be more careful.

I really understand this feeling. However, consider this: at which point is
>> something a strong typedef of something else, and when is it a new class=
?
>> Is the mechanism we want to introduce simply a way to declare a new clas=
s,
>> using another as a starting point and completely editable, or we want th=
ere
>> to be some kind of association (even if it was only on a logical level)
>> between the two things
>>
> I see that you want to add a new mechanism to define a new class using
> another class as starting point, but I would not name this a strong type
> proposal, even if it can be used to build some strong types. Whether this
> is useful by itself needs more motivation and concrete real examples.
>
I don't understand. Even what you want from a strong typing proposal is
still to define a new class from an old class. The only difference I see
between what we are talking about is that I don't think editing the old
class is useful enough compared to the downsides, and you don't.

Why would you have copied A in the first place then, rather than create a
>> new class?
>>
> Add just N bazN() functions to A and you will see why it is interesting t=
o
> modify B because B doesn't want to provide the foo function, but all the
> bazN functions.


I do see that. The problem is that once a feature is out you don't get to
tell people how to use it. And people WILL misuse having the power to alter
everything every time. I don't believe it is possible to assume that this
won't happen. Base on my personal experience, this will happen a lot, and
it will be bad.

Note that inheritance allows you to make a member not accessible.
> struct A {
>      int foo(int x) { return x * 2; }
>      double bar(double x) { return foo(x) * 4.0; }
> };
>
> struct B : A {
>      private:
>         double bar(double x);
> };


I assume that you wanted to use public inheritance. With private
inheritance being an equivalent of encapsulation, the assertion would not
be interesting, since wrapping of course removes access to the encapsulated
data. With public inheritance, you did not make that member not accessible.
It is still so, you have just hidden it.

B b;
b.A::bar(5);

There is a difference. In addition, I don't believe that two wrongs make a
right. Making a feature that can be potentially abused in the worst ways is
not wise, I think.

One of the problems of your proposal is that the copied class has access to
>> the private members, which is more subject to changes. I believe that th=
e
>> copied class should only have access to public members.
>
>
> If one creates a new class, and private members cannot be accessed, there
> will not be any way to touch them to do anything else aside from the
> original interface.
>
> Right.
>
> This is also compounded by the fact that all old methods accepting the
> original class won't work on the new class (creating an operator Base()
> should be an exception for certain use-cases, it should not be necessary =
to
> do so).
>
> The Base conversion can be protected or private. The trampoline would tak=
e
> care of this conversions.
>
> How are you going to print a copy?
>
> Hmm, using the public interface or don't.
>
> How can you convert in a custom way to the original class?
>
> I don't see the use case. Maybe you have one.
>
> How are you going to implement additional and useful methods without
> access to privates?
>
> If we need to access to private I believe it is worth creating a new
> class.


If I understand correctly, you want to be able to create a copy of another
class, with the ability to alter and access its public interface only. What
happens when you delete a public method used by a private method? What
happens when you delete a public attribute used in private code? What
happens to protected code - if not accessible you basically make
inheritance useless on it? If in all these cases your answer is "the
program will fail to compile, just copy the class by hand" then I think the
feature would be severely limited in what it could actually do.

I feel that what you are proposing is basically a fast way to create PIMPL
wrappers. If I understand correctly, you want to hide the original
completely, and just be offered an easy way to bring back some of its
interface (via trampolines) to its "wrapper", which would be the strong
typedef. Possibly adding more public methods only using the public
interface, which could be done just the same with non-member methods. The
end result is a class that cannot be extended in any meaningful way using
any of the normal C++ facilities, since every juicy bit is hidden. Applying
inheritance to it would require manual exposure of all methods, with the
limitations we have already discussed. Applying strong-typing again to a
strong-typed class would be useless as access to internals would be the
same, aside from possibly adding more data (if needed) in the public
attributes, since only those are editable. This would also prevent
encapsulation of new data. If not, it would just mean that the feature
wouldn't be used in a composable way.

My own idea is to be able to extend an already existing class into a new
class. I may not have 100% use cases for all things I'm proposing, but that
is simply because I can't write in advance all possible programs with the
feature. I just feel (maybe feeling is not enough, but opinions are also
made of these unfortunately) that if a new feature has to be introduced it
should at least try to play ball with the rest of the language. The more it
does, the more it can be used in any weird case that may come up. One of
the most beautiful things about C++ is that there's pretty much always a
way to do something, exactly because the language is flexible and its parts
can be combined in many possible ways. A feature that creates a
non-extendable object is like a dead-end.

What I mean is that these wrappers should be part of the proposal and show
> how the your copy class reach to make concrete and real opaque types as e=
..g
> the energy example in P0109.
>

But wrappers can be made in a separate library. Why should they be included
in the proposal? As long as the proposal allows them, a library only needs
to be made once (and if not needed by someone, not used).

> You see that in order to have a custom type, still many things must be
> written. So what's the difference between creating copyable wrappers (usi=
ng
> normal C++ rules), and creating a number of such interfaces (having to
> learn and teach how protected/public/private work in a new context)? I
> don't see what the difference would be. Why do you feel that wrappers on
> primitive types are not enough?
>
> Yes, the new opaque type must define all the available functions. Note
> that p0109 provides conversions and the possibility to request the compil=
er
> to generate the default trampolines. This is much sorter than defining th=
em
> using the current C++ language. Implicit conversions (public) allow to us=
e
> the new opaque type where the underlying type was expected.
>
> I would prefer the opaque type proposal to go even further (or an
> independent proposal) and be able to introduce groups of trampolines as I
> did on my Opaque library with the combined mixins. However I have no
> concrete proposal at the language level.
>

But I have made you an example with wrappers, which you also agreed is
similar to what your library currently does. So what is wrong with that
approach?

struct A {
>     A append(A const&);
> };
>
> struct B : using A {};
>
> What will be the type of x
>
> B b1, b2;
> auto x =3D b1.append(b2);
>
> IIUC your proposal, the append function will be copied replacing any
> occurrence of A by B, so it is as if B was declared
>
> struct B {
>     B append(B const&);
> };
>
> Am I missing something? (***)
>
> Or would B equivalent to
>
> struct B {
>     A append(B const&);
> };
>
> or to
>
> struct B {
>     A append(A const&);
> };
>
> I'm wondering now if the copied class could add at all new non-static dat=
a
> members. Otherwise I don't see how the duplication of such function can b=
e
> done. I suspect that p0109 doesn't allow to add new data.
> Then, if the user wants to add more data, it should first duplicate the
> class and then inherit from the duplicated class to add more data.
>

No, you understood correctly, the end result would be

struct B {
    B append(B const&);
};

Forcing the user to inherit to add more data adds inheritance, which means
that types are now implicitly convertible (to at least a common base). I
don't think this is desirable. I think strong typing should work on its own=
..

In some sense creating a new foo overload using the type-copy. However, I
> believe this would be a pretty big change.
>
> I believed this was already part of your proposal. (***)
>

Mhh, now that you put it this way. I thought about only doing this for
classes. While the mechanism for free functions would be the same (that's
what I mean by strong-typedef of a function, see below), the scope would be
wider. One only works for classes, the other on all free functions. I don't
know, maybe dividing them makes no sense. I'd love to hear what you think
about this.

> As this is outside of the scope of my proposal, I did not include this.
> And so, I cannot add to my proposal the conversion of friend and non-memb=
er
> function when creating a copy-type. If this could be included, there woul=
d
> be no problem for that.
>
> Sorry, I don't know yet what are type-aliases of methods.
>

I'll try to explain myself better. A strong typedef of a function would be
taking that function and replacing one or more types within it to others.
You could say that when you do:

template <typename T>
void foo(T);

then foo<int> and foo<double> are "strong typedefs" of each other, in some
sense. If one were allowed to do this to existing code, one could do
something like

void foo(int);

void foo(double) : using foo(int);

to use an analogous syntax to the one in my proposal. Not sure if this is
clearer, let me know.

> For example, consider
>
> struct A {};
> struct B : using A {
>     operator A() =3D default;
> };
> struct C : using B {
>     operator B() =3D default;
>     operator A() =3D default;
> };
>
> Just an idea.
>
> I'm lost.
>

What I mean is, if B is a strong typedef of A, then we can default its
conversion operator to A, right? But then, if C is a type-copy of B, then
we can default its conversion operator to both B (since it's its
type-copy), and also to A (since C is a type-copy of a type-copy).

Is it really wise to allow the compiler to be able to default convert B to
> A?
>
> I would say, yes. The question p0109 raise is whether the user wants it.
>

I'm not sure, however to me there's no difference either way.

Maybe. I thought that inherited classes are also declared without
> mentioning that they inherit, so I though that the same should hold for
> copies.
>
> Maybe, but the C++ standard doesn't have constrains on whether the class
> is derived from another class.
>

True. I'll try to think about this a bit more. Maybe we could simply lift
the restriction and let the user do what he/she wants? (so also use classes
that are not necessarily copies of the originals, as long as their
interface is compatible to what it needs to be)

> That's true, and that's mostly what I don't like about giving the ability
> to modify copied existing methods. It is definitely non-obvious that this
> is happening. If you make a mistake, it will take a long time to figure o=
ut
> that you involuntarily modified the behavior of the original class. That'=
s
> bad in my book.
>
> Maybe you need something like override to state clearly that you want to
> redefine the inherited behavior.
>

Unfortunately there would be nothing to override, as you are adding a new
overload completely separate to the old one. Both would still be usable and
work, nothing is being redefined. Simply the old function would get linked
against the new implementation. There's nothing that the compiler could do
to prevent this.

Best,
Eugenio

On Sun, Jan 1, 2017 at 4:56 PM, Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr> wrote:

> Le 31/12/2016 =C3=A0 19:39, Eugenio Bargiacchi a =C3=A9crit :
>
> Eugenio, please, preserve some additional context in your responses.
>
> From you responses, I believe that I have not understood your proposal.
> See below (***)
>
> To be honest, I will vote against this proposal if we can not modify and
>> delete existing functionality. When I copy/paste a class I can change
>> things and remove others.
>>
>
> I really understand this feeling. However, consider this: at which point
> is something a strong typedef of something else, and when is it a new
> class? Is the mechanism we want to introduce simply a way to declare a ne=
w
> class, using another as a starting point and completely editable, or we
> want there to be some kind of association (even if it was only on a logic=
al
> level) between the two things?
>
> I see that you want to add a new mechanism to define a new class using
> another class as starting point, but I would not name this a strong type
> proposal, even if it can be used to build some strong types. Whether this
> is useful by itself needs more motivation and concrete real examples.
>
>
> A mechanism that freely allows you to edit classes wouldn't be a strong
> typedef, in my opinion. Consider:
>
> struct A {
>      void foo();
> };
>
> struct B : using A {
>      void foo() =3D delete;
>      void bar();
> };
>
> Why would you have copied A in the first place then, rather than create a
> new class?
>
> Add just N bazN() functions to A and you will see why it is interesting t=
o
> modify B because B doesn't want to provide the foo function, but all the
> bazN functions.
>
> If instead you could say "copies can only add" then when you find a class
> declared as a copy you can easily reason about it. Think about a long
> chains of copies:
>
> struct A { /* .... */ };
> struct B : using A { /* .... */ };
> struct C : using B { /* .... */ };
> struct D : using C { /* .... */ };
> struct E : using D { /* .... */ };
>
> All these maybe in different files, in different places. Then what is E?
> If you are allowed to remove and change things, then you'd have to start =
at
> A and manually keep track of which things are deleted, maybe re-added
> later, maybe modified. It would be really hard to know exactly what E is.
> While if you're allowed to only increment, it would be much easier to kno=
w
> that - or at least on par with inheritance. If you can find it once in th=
e
> chain, then it exists. I believe this is an important fact that must be
> considered when thinking about what features we want in strong typing.
>
> Note that inheritance allows you to make a member not accessible.
> struct A {
>      int foo(int x) { return x * 2; }
>      double bar(double x) { return foo(x) * 4.0; }
> };
>
> struct B : A {
>      private:
>         double bar(double x);
> };
>
>
> One of the problems of your proposal is that the copied class has access
>> to the private members, which is more subject to changes. I believe that
>> the copied class should only have access to public members.
>
>
> If one creates a new class, and private members cannot be accessed, there
> will not be any way to touch them to do anything else aside from the
> original interface.
>
> Right.
>
> This is also compounded by the fact that all old methods accepting the
> original class won't work on the new class (creating an operator Base()
> should be an exception for certain use-cases, it should not be necessary =
to
> do so).
>
> The Base conversion can be protected or private. The trampoline would tak=
e
> care of this conversions.
>
> How are you going to print a copy?
>
> Hmm, using the public interface or don't.
>
> How can you convert in a custom way to the original class?
>
> I don't see the use case. Maybe you have one.
>
> How are you going to implement additional and useful methods without
> access to privates?
>
> If we need to access to private I believe it is worth creating a new
> class.
>
>
> Again, I will vote against this proposal if it doesn't provides a solutio=
n
>> for builtin types, as this is IMHO one of the most appealing use cases.
>>
>
> A solution exists, and is the one that already exists when one wants to
> limit operations done on existing types: build a wrapper. The difference =
is
> that before a completely new wrapper had to be built from scratch for eac=
h
> new needed primitive alias, depending on the required operations, with th=
is
> proposal they become easily composable, so once done it never has to be
> done again, and adding new types becomes a one-liner for the user.
>
> What I mean is that these wrappers should be part of the proposal and sho=
w
> how the your copy class reach to make concrete and real opaque types as e=
..g
> the energy example in P0109.
>
>
> Consider this against what p0109r0 does:
>
> template <class T =3D double>
> using energy =3D protected double {
>     energy operator+ (energy , energy) =3D default;
>     energy& operator*=3D(energy&, T ) =3D default;
>     energy operator*(energy , energy) =3D delete;
>     energy operator*(energy , T ) =3D default;
>     energy operator*(T , energy) =3D default;
> };
>
> You see that in order to have a custom type, still many things must be
> written. So what's the difference between creating copyable wrappers (usi=
ng
> normal C++ rules), and creating a number of such interfaces (having to
> learn and teach how protected/public/private work in a new context)? I
> don't see what the difference would be. Why do you feel that wrappers on
> primitive types are not enough?
>
> Yes, the new opaque type must define all the available functions. Note
> that p0109 provides conversions and the possibility to request the compil=
er
> to generate the default trampolines. This is much sorter than defining th=
em
> using the current C++ language. Implicit conversions (public) allow to us=
e
> the new opaque type where the underlying type was expected.
>
> I would prefer the opaque type proposal to go even further (or an
> independent proposal) and be able to introduce groups of trampolines as I
> did on my Opaque library with the combined mixins. However I have no
> concrete proposal at the language level.
>
>
> Your proposal has already this issue as you copy the whole class, and so
>> you replace every occurrence of the base class with the new class.
>>
>
> I'm not sure what you mean. In my proposal, the copy is a new class, and
> so it is always obvious what an assignment operator is going to result in=
..
> In p0109r0 this is more complex because depending on the access specifier
> different default conversion operators are defined. Not sure what you mea=
n
> when you mention the replacement that happens, and what the issue is.
>
>
>
> struct A {
>     A append(A const&);
> };
>
> struct B : using A {};
>
> What will be the type of x
>
> B b1, b2;
> auto x =3D b1.append(b2);
>
> IIUC your proposal, the append function will be copied replacing any
> occurrence of A by B, so it is as if B was declared
>
> struct B {
>     B append(B const&);
> };
>
> Am I missing something? (***)
>
> Or would B equivalent to
>
> struct B {
>     A append(B const&);
> };
>
> or to
>
> struct B {
>     A append(A const&);
> };
>
> I'm wondering now if the copied class could add at all new non-static dat=
a
> members. Otherwise I don't see how the duplication of such function can b=
e
> done. I suspect that p0109 doesn't allow to add new data.
> Then, if the user wants to add more data, it should first duplicate the
> class and then inherit from the duplicated class to add more data.
>
>
> I don't know what do you mean by type-aliases of methods. Could you
>> elaborate?
>>
>
> Yes. So consider this:
>
> struct A {
>     friend void foo(A&);
> };
>
> struct B : using A {};
>
> To me the only way to allow B to also have the friend declaration is if w=
e
> could do the following transformation:
>
> void foo(A&) ----> void foo(B&)
>
> Right.
>
>
> In some sense creating a new foo overload using the type-copy. However, I
> believe this would be a pretty big change.
>
> I believed this was already part of your proposal. (***)
>
> If such a thing was allowed, then why stop at copies? Why not being able
> to define
>
> void foo(A&) ----> void foo(C&)
>
> or even
>
> void foo(A&) ----> template<typename T> void foo(T&);
>
> As this is outside of the scope of my proposal, I did not include this.
> And so, I cannot add to my proposal the conversion of friend and non-memb=
er
> function when creating a copy-type. If this could be included, there woul=
d
> be no problem for that.
>
> Sorry, I don't know yet what are type-aliases of methods.
>
>
> Could you elaborate? (on recursive conversion operator)
>>
>
> For example, consider
>
> struct A {};
> struct B : using A {
>     operator A() =3D default;
> };
> struct C : using B {
>     operator B() =3D default;
>     operator A() =3D default;
> };
>
> Just an idea.
>
> I'm lost.
>
>
> However, this default way to define a conversion operator would be
>> disabled if the copy has added new attributes with respect to its origin=
al
>> class.
>>
>> Why?
>>
>
> I think that at that point the two classes diverged enough that the
> compiler cannot assume they can be converted freely? If I have:
>
> struct A { int x; };
> struct B : using A { int y; };
>
> Is it really wise to allow the compiler to be able to default convert B t=
o
> A?
>
> I would say, yes. The question p0109 raise is whether the user wants it.
>
> If they were the same, ok, but maybe at that point the user should be
> forced to provide a conversion operator, no?
>
> If the user decides to provide the default implementation I don't see
> where the problem is.
>
> operator Base() =3D default;
>
> The compiler know how to do the conversion.
>
>
> I don't know compiler writers would like to look ahead. I believe that C
>> should be forward declared as a copy.
>>
>
> Maybe. I thought that inherited classes are also declared without
> mentioning that they inherit, so I though that the same should hold for
> copies.
>
> Maybe, but the C++ standard doesn't have constrains on whether the class
> is derived from another class.
>
>
> I will need a concrete example of when a complete hierarchy must be
>> "duplicated". I'm not saying there are no cases, just I have no one in m=
y
>> head.
>>
>
> I'll try to add these on the concrete examples.
>
> You are not modifying here, but adding ;-). You can say it is ambiguous,
>> but we have this case with inheritance (http://melpon.org/wandbox/per
>> mlink/f9mRtE9n5mA9RPpl)
>>
>
> Not quite, the resulting copied class would be equivalent to
>
> struct C {
>      int foo(int x) { return x * 2; }
>      double foo(int x) { return x * 2; }
>      double bar(double x) { return foo(x) * 4.0; }
> };
>
> which is illegal, since you cannot overload on return type. Keep in mind
> that there is no "layer" between the original class and what gets added t=
o
> the copy.
>
> You are right. I missed that all the function are copied. In this case,
> either a function is not copied when there is an added function with the
> same overloaded signature or the program is ill formed.
>
>
> I don't see a problem here as D is a copy of A and then we are defining
>> its meaning.
>> You said that it should be as simple as if defined the class by hand.
>>
>
> That's true, and that's mostly what I don't like about giving the ability
> to modify copied existing methods. It is definitely non-obvious that this
> is happening. If you make a mistake, it will take a long time to figure o=
ut
> that you involuntarily modified the behavior of the original class. That'=
s
> bad in my book.
>
> Maybe you need something like override to state clearly that you want to
> redefine the inherited behavior.
>
>
> I believe it is worth mentioning it in the proposal. My TBoost.Opaque
>> library implements something like that. I will start a new thread to tal=
k
>> about the TBoost.Opaque library approach. If I need a library solution f=
or
>> builtin types, why this library solution will not work for classes, what
>> will be the added value of the language solution?
>>
>
> I believe that wrapper types are just as good as primitive types. This is
> also how it's always been in C++. The main problem was simply that doing
> this over and over and over was incredibly unwieldy. I don't believe that
> the reason why the older, in-C++ approaches didn't work is that they were
> creating wrappers rather than "primitive type aliases". This proposal
> eliminates the need for repetition as once done, it is done forever. A
> library like boost can pre-produce often used primitive types wrappers on=
ce
> in a single header, and be done forever.
>
> No p0109r0 doesn't define any operation by default (except conversions).
>> The user needs to add whatever is needed, maybe using the default
>> trampoline implementation). Well this is how I understand it.
>>
>
> From the proposal: "Since all member functions of the underlying type are
> known to the compiler, we can take advantage of this and therefore propos=
e
> that the compiler, by default, generate default versions of these
> trampolines."
>
> I interpret this as the compiler could generate them by default, once the
> user has requested it using the =3D default syntax. I agree the proposal
> doesn't contain examples where this is clear enough.
>
>
>
> Vicente
>
>
> On Sat, Dec 31, 2016 at 6:15 PM, Vicente J. Botet Escriba <
> vicente.botet@wanadoo.fr> wrote:
>
>> Le 31/12/2016 =C3=A0 15:57, Eugenio Bargiacchi a =C3=A9crit :
>>
>> Dear Vincente,
>>
>> Thank you for your very in-depth review. I've updated the proposal using
>> already received comments from this thread, so some things have changed,
>> but it's still alright to receive comments on this version. I'll explain
>> below how it has changed when answering to your comments.
>>
>> IIUC, every occurrence of the base type in the definition of the base
>>> type is replaced by the new type. This is one of the options described =
in
>>> Opaque proposal (see The return type issue). Why the other alternatives
>>> have less sens?
>>>
>>
>> There are many differences between my proposal and the Opaque proposal. =
I
>> believe that the main ones that this proposal brings are:
>>
>> - Where possible, do not introduce new meanings or rules to the language=
..
>> The type-copied class should behave as closely as possible to a class th=
e
>> user has implemented by hand. This should make very easy to understand h=
ow
>> the feature works, without the need to grasp many new concepts.
>> - I have removed the option to modify and remove existing functionality
>> from the class that is being copied. While I believe that this can be
>> useful, it introduces too much complexity in my opinion now. If this is
>> allowed, you basically have to create a system where you are allowed to
>> completely rewrite an existing class starting from another, since you ma=
y
>> want to copy or remove or change anything that was previously present. T=
his
>> I believe can both make the proposal unnecessary complicated, and can ma=
ke
>> the code very hard to follow, as at each new strong-typedef step (since =
a
>> type could be copied, and the copy copied again and so on) anything coul=
d
>> happen. I now believe that an incremental-only strategy (similar to
>> inheritance) can still be both useful and sufficient for most cases. Whe=
re
>> it is not, simple implementations by hand of basic functionality, extend=
ed
>> then via the type-copy mechanism should result in clear, reusable code
>> which still requires little maintenance.
>>
>> To be honest, I will vote against this proposal if we can not modify and
>> delete existing functionality. When I copy/paste a class I can change
>> things and remove others.
>>
>>
>> The word duplicating and wrapping don't match. The proposed approach
>>> doesn't wraps the underlying type, except maybe for builtin types.
>>>
>>
>> Right, I'll fix it, thanks.
>>
>> I believe the proposal needs to add some concrete examples as use cases
>>>
>>
>> This makes sense, I'll worn ok an additional section where I try to show
>> some concrete examples.
>>
>> The best will be to add them in the motivation section showing how the
>> new feature is used instead of some flat code.
>>
>>
>> If the base class change, the strong types depending on it could need
>>> maintenance also, isn't it?
>>>
>>
>> True, however wrapper methods have to be fixed 100% of the time, while a
>> type-copied class may not need this. It's the same as if one modified a
>> base class in inheritance - you don't have to necessarily update all the
>> code that depends on it right away.
>>
>> One of the problems of your proposal is that the copied class has access
>> to the private members, which is more subject to changes. I believe that
>> the copied class should only have access to public members.
>>
>>
>> In addition to these basic techniques, there are other library solution,
>>> as e.g. using CRTP that might merit to be mentioned.
>>> See [TBoost.Opaque] for a possible implementation.
>>>
>>
>> I'll add a mention to CRTP. I'll give a look at the boost link, thanks!
>>
>> Please add http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p010
>>> 9r0.pdf to this list.
>>>
>>
>> Thanks, I must have missed it.
>>
>> What is wrong for you with p0109r0 approach?
>>> What we could have with your approach that we cannot have with p0109r0?
>>> What we could have with p0109r0 that we cannot have with your approach?
>>>
>>> IIUC, p0109r0 opaque types don't introduce any operations by default
>>> other than conversions and your proposal introduce all members but no
>>> friends
>>>
>>
>> Personally, I don't think there's anything "wrong" with p0109r0. The ide=
a
>> for this proposal came to me before I knew the alternatives, but since C=
++
>> still does not have strong typedefs I thought I might as well propose an
>> alternative approach, which could possibly garner more interest.
>>
>> I believe my approach is simpler to read and more intuitive - especially
>> when creating strong aliases of very complex types, but that can definit=
ely
>> be bias. It can be applied to hierarchies of classes, since it allows
>> type-copying interdependent classes, which I believe is very important. =
It
>> is very easy to use with templates and specializations, which potentiall=
y
>> gives it a lot of power and very many potential uses. It is easily
>> composable, as in copying a copy is very easy and indeed expected in my
>> view for the feature.
>>
>> You will need to show how all this arguments applies on concrete example=
s
>> and how p0109r0 could do the same thing.
>>
>>
>> With p0109r0 there's more flexibility to alter a type. The additional
>> flexibility allows it to take on more tasks, as in type-copying friends,
>> since default ways to convert to the original types exist. It is designe=
d
>> for primitive types first, while I have actually removed them in my last
>> iteration for a number of reasons (see below).
>>
>> Again, I will vote against this proposal if it doesn't provides a
>> solution for builtin types, as this is IMHO one of the most appealing us=
e
>> cases.
>>
>> The additional flexibility however comes at a cost, as you mention the
>> return type issue, which my proposal does not have.
>>
>> Your proposal has already this issue as you copy the whole class, and so
>> you replace every occurrence of the base class with the new class.
>>
>>
>> I don't introduce friends mostly because a feature to create type-aliase=
s
>> of methods does not currently exist,
>>
>> I don't know what do you mean by type-aliases of methods. Could you
>> elaborate?
>>
>> and I don't believe it is wise to add it to the scope of this proposal
>> since it would be another very large change. If such a feature existed,
>> however, adding friends to a type-copied class in my proposal would be
>> trivial, as simply strong typedefs of the needed functions could be crea=
ted
>> on the fly. The same could also be done for non-member functions if need=
ed,
>> but how that would work I have not thought about yet.
>>
>> Could you elaborate how type-aliases of methods would help here?
>>
>>
>> I find that conversions to/from the underlying type must be covered by
>>> the proposal. If we change the Base type we don't want to be forced to
>>> redefine the conversion operator.
>>> Maybe we need some kind of default conversion implementation
>>>     operator Base() *=3D default*;
>>> or
>>>     *explicit* operator Base() *=3D default*;
>>>
>>
>> I like this. I didn't add it to keep the number of features as low as
>> reasonably possible, but this is simple enough. This could also be used
>> recursively, as in a copy of a copy could define a conversion operator t=
o
>> both the first copy and the original in this way.
>>
>> Could you elaborate?
>>
>> However, this default way to define a conversion operator would be
>> disabled if the copy has added new attributes with respect to its origin=
al
>> class.
>>
>> Why?
>>
>>
>> Why do you introduce this restriction? (on template parameter numbers)
>>>
>>
>> No actually, you're right. I should lift it. I thought initially that
>> there wouldn't be any reason to add more template parameters, as they wo=
uld
>> only be needed to satisfy the original class. But this is definitely wro=
ng.
>> I'll change it, thanks.
>>
>> In ** above C has not yet defined as a copy
>>>
>>
>> Ill explain how I believe this example should work. Since C has been
>> declared but not defined when parsing D, the compiler will be allowed to
>> assume that C is going to be defined later as a type-copy of A. If that
>> does not happen, then the compiler will give an error, either at the
>> definition of C or of D, explaining that D assumed that C would have bee=
n a
>> type-copy while it was not. If C has added new attributes to its
>> declaration though D's definition would need to take the new size of C i=
nto
>> account though. Not sure if this can be done or if it should result in a=
n
>> error.
>>
>> I don't know compiler writers would like to look ahead. I believe that C
>> should be forward declared as a copy.
>>
>>
>> I believe this interdependent case introduce a lot of complexity. We
>>> would need a good use case to introduce it on the standard.
>>>
>>
>> A very simple example would be copying of inherited classes, both base
>> and derived. Without a way to do this that just cannot be done. This can=
 be
>> important if one does not want that the derived type and its type-copy a=
re
>> allowed to be converted to the same base. This is a strong reason, I
>> believe, otherwise strong-typing in that case just lost some power in
>> keeping original and type-copy apart.
>>
>> I will need a concrete example of when a complete hierarchy must be
>> "duplicated". I'm not saying there are no cases, just I have no one in m=
y
>> head.
>>
>>
>> I believe that this cannot be optional as in a lot of cases we need to
>>> modify/restrict the base type interface.
>>>
>>
>> I have actually removed this in my newest revision. I believe that
>> ground-up building of types is the better way to go (as is normally done=
 in
>> inheritance). Having the power to completely alter the original type,
>> possibly to a point where there was not even much in common between the
>> original and the type-copy, is not worth it. This is a personal opinion,
>> but I believe doing so can prevent some very complex and ugly code smell=
s,
>> at a not incredible cost.
>>
>> We need to solve concrete problems. The 1st use case I have for strongly
>> types is to reduce the interface provided by the underlying type and to
>> adapt the functions signatures to the new class.
>>
>>
>> Could you give a concrete example of this kind of problems?
>>>
>>
>> Suppose
>>
>> struct A {
>>      int foo(int x) { return x * 2; }
>>      double bar(double x) { return foo(x) * 4.0; }
>> };
>>
>> struct B : using A {
>>     int foo(int) =3D delete;
>>     // bar cannot compile anymore
>> };
>>
>> Where is the problem? struct B will not compile. That's all.
>>
>> struct C : using A {
>>     double foo(int x) { return x * 2; }
>>     // ambiguous definition
>> };
>>
>> You are not modifying here, but adding ;-). You can say it is ambiguous,
>> but we have this case with inheritance (http://melpon.org/wandbox/per
>> mlink/f9mRtE9n5mA9RPpl)
>>
>> struct D : using A {
>>     double foo(double x) { return x * 3; }
>>     // Changes meaning of bar underhandedly with no warning
>> };
>>
>> I don't see a problem here as D is a copy of A and then we are defining
>> its meaning.
>> You said that it should be as simple as if defined the class by hand.
>>
>> I suppose even more dangerous and complex cases could be devised.
>>
>> We will need some real examples to see how dangerous they are ;-)
>>
>>
>> While this is inline with your approach, this merits some explanations a=
s
>>> the operators are no members. Shouldn't the operators of UDT classes me=
ritt
>>> to be inherited as well?
>>>
>>
>> I've removed primitive type support also for this reason. They are not
>> currently treated as classes by C++, and so I think I shouldn't either.
>> Instead my approach is now constructive. If one needed aliases for
>> primitive types, one could create a single header of wrappers in the for=
m
>>
>> template <typename T>
>> class SimpleWrapper {
>>     public:
>>         SimpleWrapper(T t) : t_(t) {}
>>
>>     private:
>>         T t_;
>> };
>>
>> template <typename T>
>> struct SimpleWrapperWithSum : using SimpleWrapper<T> {
>>     SimpleWrapperWithSum operator+(const SimpleWrapperWithSum & other) {
>> return t_ + other.t_; }
>> };
>>
>> And so on. It would only be needed once, and then users could simply cop=
y
>> the versions with the operators they need to use. It's not incredibly
>> pretty and it does have some limitations, but it works,
>>
>> I believe it is worth mentioning it in the proposal. My TBoost.Opaque
>> library implements something like that. I will start a new thread to tal=
k
>> about the TBoost.Opaque library approach. If I need a library solution f=
or
>> builtin types, why this library solution will not work for classes, what
>> will be the added value of the language solution?
>>
>> and in any case even in p0109r0 one would need to remove all unneeded
>> operators, so work would need to be done anyway.
>>
>> No p0109r0 doesn't define any operation by default (except conversions).
>> The user needs to add whatever is needed, maybe using the default
>> trampoline implementation). Well this is how I understand it.
>>
>>
>> I believed that there where no implicit conversions on your proposals.
>>> How (*this) is converted to an int?
>>>
>>> What would be the result type of x below?
>>>
>>> Id id(1);
>>> auto x =3D +id;
>>>
>>> I suspect that it would be Id.
>>>
>> Yeah, this was a weird syntax, I thought it could be a simple way to
>> represent conversion to the underlying primitive type.
>>
>> The type of the operation would be Id, yes. I believe that to be the onl=
y
>> intuitive result that makes sense, unless an explicit operator+ that doe=
s a
>> conversion has been defined somewhere. If a cast is needed, one needs to
>> cast. I don't see a reason to change that for strong typedefs, otherwise
>> the language would be inconsistent IMO.
>>
>> Why this restriction is needed or desirable. (w.r.t. final in
>>> type-copies of primitive types)
>>>
>>
>> It is not. But I believe that if one needs to do something, it has to be
>> in line with the rest of the language. If a strong typedef of a primitiv=
e
>> type is needed, it would still need to follow the rules of primitive typ=
es.
>>
>> It depends. If a strong type is able to define new members it is not
>> anymore a builtin and becomes for me a class.
>>
>> As primitive types are not inheritable, I believe neither should the
>> strong typedefs. Maybe this is a wrong position, I don't know (since
>> primitive typedefs are not inheritable due to C compatibilities IIUC), b=
ut
>> I believe that having consistency is still useful for a proposal. Otherw=
ise
>> one needs to always learn a million exceptions to each rule, and that I
>> don't like, where it can be avoided. In any case, these are my opinions,
>> but if there is strong consensus to change how the proposal works I have=
 no
>> problem in modifying it.
>>
>> You need to justify your decisions on a rationale section. But as you
>> have removed builtin types as base types this is not needed anymore. You
>> will need to justify why builtin are not supported :(
>>
>>
>> Example of where this can be useful welcome.
>>>
>>
>> I must admit I didn't really think about this, I just thought they could
>> be nice to have. Maybe they would be useless. I just considered that
>> sometimes the ingenuity of how people use tools always seem to surprise,=
 so
>> why not. Maybe in order to SFINAE the generation of conversion operators=
 to
>> classes, given that they are copies of the original? Something like
>>
>> struct Copy : using A {
>>      template <typename T, /* enable_if_t<is_copy_of_v<T, A>>> */>
>>      operator T =3D default;
>> };
>>
>> Features must be added to solve concrete problems.
>>
>> I suggest you to work on the motivation section with real concrete
>> examples.
>>
>>
>> How other type traits behave for the copied class (see p0109r0)?
>>>
>>
>> All other type traits behave as if the class had been implemented by
>> hand, and is separate from the original. so is_same would return false, =
for
>> example. It seems that p0109r0 thinks the same way. The only difference =
is
>> that sizeof may be different, since in my proposal one could add additio=
nal
>> attributes to the type-copied class. (There's no examples in the old
>> version, I've added them on GitHub though).
>>
>> I agree for is_same of course. I was wondering for other traits that
>> could have been specialized for the base class. I suspect the answer is
>> that the user would need to specialize the new type again.
>>
>>
>> Thanks again for your feedback.
>>
>> You are welcome,
>> Vicente
>>
>> --
>> 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/gkJUVnL-Fmg/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/f4a57116-c65b-94f4-51f2-
>> e5cf8b4ff3ca%40wanadoo.fr
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f4a57116-c=
65b-94f4-51f2-e5cf8b4ff3ca%40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfoo=
ter>
>> .
>>
>
> --
> 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%2BtVBKZOMtpURNBDCEJijFL_J5s%
> 2BROrLwJfkRgGyWzZMgg%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2B=
tVBKZOMtpURNBDCEJijFL_J5s%2BROrLwJfkRgGyWzZMgg%40mail.gmail.com?utm_medium=
=3Demail&utm_source=3Dfooter>
> .
>
>
> --
> 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/gkJUVnL-Fmg/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/ef8190c7-f46f-cf76-
> 7e45-2114a84eae27%40wanadoo.fr
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ef8190c7-f4=
6f-cf76-7e45-2114a84eae27%40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=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/CAHfn%3D%2BtEbHpzdtK40qS_tVUPfPyKnOft-ZXOTMTDezP=
DzS3fAw%40mail.gmail.com.

--94eb2c03c7908d1bfd05450bbbd4
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Dear Vicente,<br><br><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddi=
ng-left:1ex">Eugenio, please, preserve some additional context in your
      responses.<br></blockquote><div><br></div><div>Sorry, I&#39;ll try to=
 be more careful. <br></div><br><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D"gma=
il-im"><div dir=3D"ltr"><div>I really understand this feeling. However, con=
sider this:
          at which point is something a strong typedef of something
          else, and when is it a new class? Is the mechanism we want to
          introduce simply a way to declare a new class, using another
          as a starting point and completely editable, or we want there
          to be some kind of association (even if it was only on a
          logical level) between the two things</div></div></span></blockqu=
ote><span class=3D"gmail-im"><div dir=3D"ltr"><div>
        </div></div></span><blockquote><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><span class=3D"gmail-im"><blockquote type=3D"cite"><div dir=
=3D"ltr">
      </div>
    </blockquote></span></blockquote></blockquote>
    I see that you want to add a new mechanism to define a new class
    using another class as starting point, but I would not name this a
    strong type proposal, even if it can be used to build some strong
    types. Whether this is useful by itself needs more motivation and
    concrete real examples.<span class=3D"gmail-im"></span><br></blockquote=
><div><blockquote><div><span class=3D"gmail-im"></span></div></blockquote><=
span class=3D"gmail-im">
    </span>I don&#39;t understand. Even what you want from a strong typing =
proposal is still to define a new class from an old class. The only differe=
nce I see between what we are talking about is that I don&#39;t think editi=
ng the old class is useful enough compared to the downsides, and you don&#3=
9;t.<br><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-im"><div dir=3D"l=
tr"><div>Why would you have copied A in the first place then, rather
          than create a new class? </div></div></span></blockquote><span cl=
ass=3D"gmail-im"><blockquote type=3D"cite"><div dir=3D"ltr">
      </div>
    </blockquote></span>
    Add just N bazN() functions to A and you will see why it is
    interesting to modify B because B doesn&#39;t want to provide the foo
    function, but all the bazN functions.</blockquote><div><br></div><div>I=
 do see that. The problem is that once a feature is out you don&#39;t get t=
o tell people how to use it. And people WILL misuse having the power to alt=
er everything every time. I don&#39;t believe it is possible to assume that=
 this won&#39;t happen. Base on my personal experience, this will happen a =
lot, and it will be bad.<br></div><span class=3D"gmail-im"></span><br><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex">Note that inheritance allows y=
ou to make a member not accessible.<span class=3D"gmail-im"></span><br><spa=
n class=3D"gmail-im">
    struct A {</span><br><span class=3D"gmail-im">
    =C2=A0=C2=A0=C2=A0=C2=A0 int foo(int x) { return x * 2; }</span><br><sp=
an class=3D"gmail-im">
    =C2=A0=C2=A0=C2=A0=C2=A0 double bar(double x) { return foo(x) * 4.0; }<=
/span><br><span class=3D"gmail-im">
    };</span><br><span class=3D"gmail-im">
    </span><br><span class=3D"gmail-im"></span>
    struct B : A {<br>
    =C2=A0=C2=A0=C2=A0=C2=A0 private:<br>
    =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 double bar(double x);<br>
    };</blockquote><div><br></div><div>I assume that you wanted to use publ=
ic inheritance. With private inheritance being an equivalent of encapsulati=
on, the assertion would not be interesting, since wrapping of course remove=
s access to the encapsulated data. With public inheritance, you did not mak=
e that member not accessible. It is still so, you have just hidden it.<br><=
br>B b;<br>b.A::bar(5);<br><br></div><div>There is a difference. In additio=
n, I don&#39;t believe that two wrongs make a right. Making a feature that =
can be potentially abused in the worst ways is not wise, I think.<br><br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-im"><b=
lockquote type=3D"cite"><div dir=3D"ltr"><div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex">One of the problems of
            your proposal is that the copied class has access to the
            private members, which is more subject to changes. I believe
            that the copied class should only have access to public
            members.</blockquote>
          <div><br>
          </div>
          If one creates a new class, and private members cannot be
          accessed, there will not be any way to touch them to do
          anything else aside from the original interface. </div>
      </div>
    </blockquote></span>
    Right.<span class=3D"gmail-im"><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>This is also compounded by the fact that all old methods
          accepting the original class won&#39;t work on the new class
          (creating an operator Base() should be an exception for
          certain use-cases, it should not be necessary to do so). </div>
      </div>
    </blockquote></span>
    The Base conversion can be protected or private. The trampoline
    would take care of this conversions.<span class=3D"gmail-im"><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>How are you going to print a copy? </div>
      </div>
    </blockquote></span>
    Hmm, using the public interface or don&#39;t.<span class=3D"gmail-im"><=
br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>How can you convert in a custom way to the original class?</di=
v>
      </div>
    </blockquote></span>
    I don&#39;t see the use case. Maybe you have one.<span class=3D"gmail-i=
m"><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div> How are you going to implement additional and useful
          methods without access to privates?<br>
        </div>
      </div>
    </blockquote></span>
    If we need to access to private I believe it is worth creating a new
    class. </blockquote><div><br></div><div>If I understand correctly, you =
want to be able to create a copy of another class, with the ability to alte=
r and access its public interface only. What happens when you delete a publ=
ic method used by a private method? What happens when you delete a public a=
ttribute used in private code? What happens to protected code - if not acce=
ssible you basically make inheritance useless on it? If in all these cases =
your answer is &quot;the program will fail to compile, just copy the class =
by hand&quot; then I think the feature would be severely limited in what it=
 could actually do.<br></div><div><br></div><div>I feel that what you are p=
roposing is basically a fast way to create PIMPL wrappers. If I understand =
correctly, you want to hide the original completely, and just be offered an=
 easy way to bring back some of its interface (via trampolines) to its &quo=
t;wrapper&quot;, which would be the strong typedef. Possibly adding more pu=
blic methods only using the public interface, which could be done just the =
same with non-member methods. The end result is a class that cannot be exte=
nded in any meaningful way using any of the normal C++ facilities, since ev=
ery juicy bit is hidden. Applying inheritance to it would require manual ex=
posure of all methods, with the limitations we have already discussed. Appl=
ying strong-typing again to a strong-typed class would be useless as access=
 to internals would be the same, aside from possibly adding more data (if n=
eeded) in the public attributes, since only those are editable. This would =
also prevent encapsulation of new data. If not, it would just mean that the=
 feature wouldn&#39;t be used in a composable way.<br><br></div><div>My own=
 idea is to be able to extend an already existing class into a new class. I=
 may not have 100% use cases for all things I&#39;m proposing, but that is =
simply because I can&#39;t write in advance all possible programs with the =
feature. I just feel (maybe feeling is not enough, but opinions are also ma=
de of these unfortunately) that if a new feature has to be introduced it sh=
ould at least try to play ball with the rest of the language. The more it d=
oes, the more it can be used in any weird case that may come up. One of the=
 most beautiful things about C++ is that there&#39;s pretty much always a w=
ay to do something, exactly because the language is flexible and its parts =
can be combined in many possible ways. A feature that creates a non-extenda=
ble object is like a dead-end.<br><br><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddi=
ng-left:1ex">What I mean is that these wrappers should be part of the propo=
sal
    and show how the your copy class reach to make concrete and real
    opaque types as e.g the energy example in P0109.<span class=3D"gmail-im=
"></span><br><span class=3D"gmail-im"></span></blockquote><br></div><div>Bu=
t wrappers can be made in a separate library. Why should they be included i=
n the proposal? As long as the proposal allows them, a library only needs t=
o be made once (and if not needed by someone, not used).<br></div><div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-im"><blo=
ckquote type=3D"cite"><div dir=3D"ltr"><div>You see that in order to have a=
 custom type, still many
          things must be written. So what&#39;s the difference between
          creating copyable wrappers (using normal C++ rules), and
          creating a number of such interfaces (having to learn and
          teach how protected/public/private work in a new context)? I
          don&#39;t see what the difference would be. Why do you feel that
          wrappers on primitive types are not enough?<br>
        </div>
      </div>
    </blockquote></span>
    Yes, the new opaque type must define all the available functions.
    Note that p0109 provides conversions and the possibility to request
    the compiler to generate the default trampolines. This is much
    sorter than defining them using the current C++ language. Implicit
    conversions (public) allow to use the new opaque type where the
    underlying type was expected. <br>
    <br>
    I would prefer the opaque type proposal to go even further (or an
    independent proposal) and be able to introduce groups of trampolines
    as I did on my Opaque library with the combined mixins. However I
    have no concrete proposal at the language level. <br></blockquote><div>=
<br></div><div>But I have made you an example with wrappers, which you also=
 agreed is similar to what your library currently does. So what is wrong wi=
th that approach? <br></div><div><br><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddin=
g-left:1ex"><div>struct A {<br>
    </div>
    =C2=A0 =C2=A0 A append(A const&amp;);<br>
    };<br>
    <br>
    struct B : using A {};<br>
    <br>
    What will be the type of x<br>
    <br>
    B b1, b2;<br>
    auto x =3D b1.append(b2);<br>
    <br>
    IIUC your proposal, the append function will be copied replacing any
    occurrence of A by B, so it is as if B was declared<br>
    <br>
    <div>struct B {<br>
    </div>
    =C2=A0 =C2=A0 B append(B const&amp;);<br>
    };<br>
    <br>
    Am I missing something? (***)<br>
    <br>
    Or would B equivalent to<br>
    <br>
    <div>struct B {<br>
    </div>
    =C2=A0 =C2=A0 A append(B const&amp;);<br>
    };<br>
    <br>
    or to<br>
    <br>
    <div>struct B {<br>
    </div>
    =C2=A0 =C2=A0 A append(A const&amp;);<br>
    };<br>
    <br>
    I&#39;m wondering now if the copied class could add at all new
    non-static data members. Otherwise I don&#39;t see how the duplication
    of such function can be done. I suspect that p0109 doesn&#39;t allow to
    add new data.<br>
    Then, if the user wants to add more data, it should first duplicate
    the class and then inherit from the duplicated class to add more
    data.<span class=3D"gmail-im"><br></span></blockquote><br></div><div>No=
, you understood correctly, the end result would be <br><br></div><div><div=
>struct B {<br>
    </div>
    =C2=A0 =C2=A0 B append(B const&amp;);<br>
    };<br>
    <br></div><div>Forcing the user to inherit to add more data adds inheri=
tance, which means that types are now implicitly convertible (to at least a=
 common base). I don&#39;t think this is desirable. I think strong typing s=
hould work on its own.<br><br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex"><span class=3D"gmail-im"><blockquote type=3D"cite"><div dir=3D"ltr"><d=
iv><div>In some sense creating a new foo overload using the
            type-copy. However, I believe this would be a pretty big
            change. </div>
        </div>
      </div>
    </blockquote></span>
    I believed this was already part of your proposal. (***)<span class=3D"=
gmail-im"><br></span></blockquote><div><br></div><div>Mhh, now that you put=
 it this way. I thought about only doing this for classes. While the mechan=
ism for free functions would be the same (that&#39;s what I mean by strong-=
typedef of a function, see below), the scope would be wider. One only works=
 for classes, the other on all free functions. I don&#39;t know, maybe divi=
ding them makes no sense. I&#39;d love to hear what you think about this.<b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-im=
"><blockquote type=3D"cite"><div dir=3D"ltr"><div><div>As this is outside o=
f the scope of my proposal, I did not
            include this. And so, I cannot add to my proposal the
            conversion of friend and non-member function when creating a
            copy-type. If this could be included, there would be no
            problem for that.<br>
          </div>
        </div>
      </div>
    </blockquote></span>
    Sorry, I don&#39;t know yet what are type-aliases of methods. <br></blo=
ckquote><div><br></div><div>I&#39;ll try to explain myself better. A strong=
 typedef of a function would be taking that function and replacing one or m=
ore types within it to others. You could say that when you do:<br><br></div=
><div>template &lt;typename T&gt;<br></div><div>void foo(T);<br><br></div><=
div>then foo&lt;int&gt; and foo&lt;double&gt; are &quot;strong typedefs&quo=
t; of each other, in some sense. If one were allowed to do this to existing=
 code, one could do something like<br><br></div><div>void foo(int);<br><br>=
</div><div>void foo(double) : using foo(int);<br><br></div><div>to use an a=
nalogous syntax to the one in my proposal. Not sure if this is clearer, let=
 me know.<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=
=3D"gmail-im"><blockquote type=3D"cite"><div dir=3D"ltr"><div><div><div>For=
 example, consider<br>
              <br>
            </div>
            <div>struct A {};<br>
            </div>
            <div>struct B : using A {<br>
            </div>
            <div>=C2=A0=C2=A0=C2=A0 operator A() =3D default;<br>
            </div>
            <div>};<br>
            </div>
            <div>struct C : using B {<br>
            </div>
            <div>=C2=A0=C2=A0=C2=A0 operator B() =3D default;<br>
            </div>
            <div>=C2=A0=C2=A0=C2=A0 operator A() =3D default;<br>
              };<br>
              <br>
            </div>
            <div>Just an idea.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I&#39;m lost.<span class=3D"gmail-im"><br></span></blockquote><div><br>=
</div><div>What I mean is, if B is a strong typedef of A, then we can defau=
lt its conversion operator to A, right? But then, if C is a type-copy of B,=
 then we can default its conversion operator to both B (since it&#39;s its =
type-copy), and also to A (since C is a type-copy of a type-copy).<br><br><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-im"><=
blockquote type=3D"cite"><div dir=3D"ltr"><div><div><div><div>Is it really =
wise to allow the compiler to be able to
                default convert B to A? </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I would say, yes. The question p0109 raise is whether the user wants
    it.<span class=3D"gmail-im"><br></span></blockquote><div><br></div><div=
>I&#39;m not sure, however to me there&#39;s no difference either way.<br><=
br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-i=
m"><blockquote type=3D"cite"><div dir=3D"ltr"><div><div><div><div>Maybe. I =
thought that inherited classes are also
                declared without mentioning that they inherit, so I
                though that the same should hold for copies.<br>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Maybe, but the C++ standard doesn&#39;t have constrains on whether the
    class is derived from another class.<span class=3D"gmail-im"><br></span=
></blockquote><div><br></div><div>True. I&#39;ll try to think about this a =
bit more. Maybe we could simply lift the restriction and let the user do wh=
at he/she wants? (so also use classes that are not necessarily copies of th=
e originals, as long as their interface is compatible to what it needs to b=
e) <span class=3D"gmail-im"><br></span><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><span class=3D"gmail-im"><blockquote type=3D"cite"><div dir=
=3D"ltr"><div><div><div><div><div>That&#39;s true, and that&#39;s mostly wh=
at I don&#39;t like
                  about giving the ability to modify copied existing
                  methods. It is definitely non-obvious that this is
                  happening. If you make a mistake, it will take a long
                  time to figure out that you involuntarily modified the
                  behavior of the original class. That&#39;s bad in my book=
..<br>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Maybe you need something like override to state clearly that you
    want to redefine the inherited behavior.<span class=3D"gmail-im"><br></=
span></blockquote><div><br></div><div>Unfortunately there would be nothing =
to override, as you are adding a new overload completely separate to the ol=
d one. Both would still be usable and work, nothing is being redefined. Sim=
ply the old function would get linked against the new implementation. There=
&#39;s nothing that the compiler could do to prevent this.<br><br></div><di=
v>Best,<br></div><div>Eugenio<br></div></div> </div></div></div></div></div=
></div></div></div></div><div class=3D"gmail_extra"><br><div class=3D"gmail=
_quote">On Sun, Jan 1, 2017 at 4:56 PM, Vicente J. Botet Escriba <span dir=
=3D"ltr">&lt;<a href=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_blank">=
vicente.botet@wanadoo.fr</a>&gt;</span> wrote:<br><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"m_847778784893274403moz-cite-prefix">Le 31/12/2016 =C3=A0=
 19:39, Eugenio
      Bargiacchi a =C3=A9crit=C2=A0:<br>
      <br>
      Eugenio, please, preserve some additional context in your
      responses.<br>
      <br>
      From you responses, I believe that I have not understood your
      proposal. See below (***)<br>
    </div><span class=3D"">
    <blockquote type=3D"cite">
      <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">To
          be honest, I will vote against this proposal if we can not
          modify and delete existing functionality. When I copy/paste a
          class I can change things and remove others.<span class=3D"m_8477=
78784893274403gmail-im"></span><br>
        </blockquote>
        <div><br>
        </div>
        <div>I really understand this feeling. However, consider this:
          at which point is something a strong typedef of something
          else, and when is it a new class? Is the mechanism we want to
          introduce simply a way to declare a new class, using another
          as a starting point and completely editable, or we want there
          to be some kind of association (even if it was only on a
          logical level) between the two things?<br>
        </div>
      </div>
    </blockquote></span>
    I see that you want to add a new mechanism to define a new class
    using another class as starting point, but I would not name this a
    strong type proposal, even if it can be used to build some strong
    types. Whether this is useful by itself needs more motivation and
    concrete real examples.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <div>A mechanism that freely allows you to edit classes wouldn&#39;=
t
          be a strong typedef, in my opinion. Consider:<br>
          <br>
        </div>
        <div>struct A {<br>
        </div>
        <div>=C2=A0=C2=A0=C2=A0=C2=A0 void foo();<br>
          };<br>
          <br>
        </div>
        <div>struct B : using A {<br>
        </div>
        <div>=C2=A0=C2=A0=C2=A0=C2=A0 void foo() =3D delete;<br>
        </div>
        <div>=C2=A0=C2=A0=C2=A0=C2=A0 void bar();<br>
          };<br>
          <br>
        </div>
        <div>Why would you have copied A in the first place then, rather
          than create a new class? </div>
      </div>
    </blockquote></span>
    Add just N bazN() functions to A and you will see why it is
    interesting to modify B because B doesn&#39;t want to provide the foo
    function, but all the bazN functions.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>If instead you could say &quot;copies can only add&quot; then =
when
          you find a class declared as a copy you can easily reason
          about it. Think about a long chains of copies:<br>
          <br>
        </div>
        <div>struct A { /* .... */ };<br>
          struct B : using A { /* .... */ };<br>
          struct C : using B { /* .... */ };<br>
          struct D : using C { /* .... */ };<br>
          struct E : using D { /* .... */ };<br>
          <br>
        </div>
      </div>
    </blockquote>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>All these maybe in different files, in different places.
          Then what is E? If you are allowed to remove and change
          things, then you&#39;d have to start at A and manually keep track
          of which things are deleted, maybe re-added later, maybe
          modified. It would be really hard to know exactly what E is.
          While if you&#39;re allowed to only increment, it would be much
          easier to know that - or at least on par with inheritance. If
          you can find it once in the chain, then it exists. I believe
          this is an important fact that must be considered when
          thinking about what features we want in strong typing.<br>
        </div>
      </div>
    </blockquote></span>
    Note that inheritance allows you to make a member not accessible.<span =
class=3D""><br>
    struct A {<br>
    =C2=A0=C2=A0=C2=A0=C2=A0 int foo(int x) { return x * 2; }<br>
    =C2=A0=C2=A0=C2=A0=C2=A0 double bar(double x) { return foo(x) * 4.0; }<=
br>
    };<br>
    <br></span>
    struct B : A {<br>
    =C2=A0=C2=A0=C2=A0=C2=A0 private:<br>
    =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 double bar(double x);<br>
    };<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          <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">One of the prob=
lems of
            your proposal is that the copied class has access to the
            private members, which is more subject to changes. I believe
            that the copied class should only have access to public
            members.</blockquote>
          <div><br>
          </div>
          If one creates a new class, and private members cannot be
          accessed, there will not be any way to touch them to do
          anything else aside from the original interface. </div>
      </div>
    </blockquote></span>
    Right.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>This is also compounded by the fact that all old methods
          accepting the original class won&#39;t work on the new class
          (creating an operator Base() should be an exception for
          certain use-cases, it should not be necessary to do so). </div>
      </div>
    </blockquote></span>
    The Base conversion can be protected or private. The trampoline
    would take care of this conversions.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>How are you going to print a copy? </div>
      </div>
    </blockquote></span>
    Hmm, using the public interface or don&#39;t.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>How can you convert in a custom way to the original class?</di=
v>
      </div>
    </blockquote></span>
    I don&#39;t see the use case. Maybe you have one.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div> How are you going to implement additional and useful
          methods without access to privates?<br>
        </div>
      </div>
    </blockquote></span>
    If we need to access to private I believe it is worth creating a new
    class. <br><span class=3D"">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><span class=3D"m_847778784893274403gmail-im"></span><br>
          <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">Again, I will v=
ote
            against this proposal if it doesn&#39;t provides a solution for
            builtin types, as this is IMHO one of the most appealing use
            cases.<span class=3D"m_847778784893274403gmail-im"></span><br>
            <span class=3D"m_847778784893274403gmail-im"></span></blockquot=
e>
          <br>
        </div>
        <div>A solution exists, and is the one that already exists when
          one wants to limit operations done on existing types: build a
          wrapper. The difference is that before a completely new
          wrapper had to be built from scratch for each new needed
          primitive alias, depending on the required operations, with
          this proposal they become easily composable, so once done it
          never has to be done again, and adding new types becomes a
          one-liner for the user.<br>
        </div>
      </div>
    </blockquote></span>
    What I mean is that these wrappers should be part of the proposal
    and show how the your copy class reach to make concrete and real
    opaque types as e.g the energy example in P0109.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <div>Consider this against what p0109r0 does:<br>
          <br>
          <div><font size=3D"2"><span style=3D"font-family:arial,helvetica,=
sans-serif">template
                &lt;class T =3D double&gt;</span></font></div>
          <div><font size=3D"2"><span style=3D"font-family:arial,helvetica,=
sans-serif">using
                energy =3D protected double {</span></font></div>
          <div><font size=3D"2"><span style=3D"font-family:arial,helvetica,=
sans-serif">=C2=A0=C2=A0=C2=A0
                energy operator+ (energy , energy) =3D default;</span></fon=
t></div>
          <div><font size=3D"2"><span style=3D"font-family:arial,helvetica,=
sans-serif">=C2=A0=C2=A0=C2=A0
                energy&amp; operator*=3D(energy&amp;, T ) =3D default;</spa=
n></font></div>
          <div><font size=3D"2"><span style=3D"font-family:arial,helvetica,=
sans-serif">=C2=A0=C2=A0=C2=A0
                energy operator*(energy , energy) =3D delete;</span></font>=
</div>
          <div><font size=3D"2"><span style=3D"font-family:arial,helvetica,=
sans-serif">=C2=A0=C2=A0=C2=A0
                energy operator*(energy , T ) =3D default;</span></font></d=
iv>
          <div><font size=3D"2"><span style=3D"font-family:arial,helvetica,=
sans-serif">=C2=A0=C2=A0=C2=A0
                energy operator*(T , energy) =3D default;</span></font></di=
v>
          <div><font size=3D"2"><span style=3D"font-family:arial,helvetica,=
sans-serif">};</span></font></div>
          <br>
        </div>
        <div>You see that in order to have a custom type, still many
          things must be written. So what&#39;s the difference between
          creating copyable wrappers (using normal C++ rules), and
          creating a number of such interfaces (having to learn and
          teach how protected/public/private work in a new context)? I
          don&#39;t see what the difference would be. Why do you feel that
          wrappers on primitive types are not enough?<br>
        </div>
      </div>
    </blockquote></span>
    Yes, the new opaque type must define all the available functions.
    Note that p0109 provides conversions and the possibility to request
    the compiler to generate the default trampolines. This is much
    sorter than defining them using the current C++ language. Implicit
    conversions (public) allow to use the new opaque type where the
    underlying type was expected. <br>
    <br>
    I would prefer the opaque type proposal to go even further (or an
    independent proposal) and be able to introduce groups of trampolines
    as I did on my Opaque library with the combined mixins. However I
    have no concrete proposal at the language level. <br><span class=3D"">
    <font size=3D"2"><span style=3D"font-family:arial,helvetica,sans-serif"=
><br>
      </span></font>
    <br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <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">Your proposal h=
as already
            this issue as you copy the whole class, and so you replace
            every occurrence of the base class with the new class.<span cla=
ss=3D"m_847778784893274403gmail-im"><br>
            </span></blockquote>
          <div><br>
          </div>
          <div>I&#39;m not sure what you mean. In my proposal, the copy is =
a
            new class, and so it is always obvious what an assignment
            operator is going to result in. In p0109r0 this is more
            complex because depending on the access specifier different
            default conversion operators are defined. Not sure what you
            mean when you mention the replacement that happens, and what
            the issue is.<br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    </span><div>struct A {<br>
    </div>
    =C2=A0 =C2=A0 A append(A const&amp;);<br>
    };<br>
    <br>
    struct B : using A {};<br>
    <br>
    What will be the type of x<br>
    <br>
    B b1, b2;<br>
    auto x =3D b1.append(b2);<br>
    <br>
    IIUC your proposal, the append function will be copied replacing any
    occurrence of A by B, so it is as if B was declared<br>
    <br>
    <div>struct B {<br>
    </div>
    =C2=A0 =C2=A0 B append(B const&amp;);<br>
    };<br>
    <br>
    Am I missing something? (***)<br>
    <br>
    Or would B equivalent to<br>
    <br>
    <div>struct B {<br>
    </div>
    =C2=A0 =C2=A0 A append(B const&amp;);<br>
    };<br>
    <br>
    or to<br>
    <br>
    <div>struct B {<br>
    </div>
    =C2=A0 =C2=A0 A append(A const&amp;);<br>
    };<br>
    <br>
    I&#39;m wondering now if the copied class could add at all new
    non-static data members. Otherwise I don&#39;t see how the duplication
    of such function can be done. I suspect that p0109 doesn&#39;t allow to
    add new data.<br>
    Then, if the user wants to add more data, it should first duplicate
    the class and then inherit from the duplicated class to add more
    data.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div><br>
            <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I don&#39;t k=
now what do
              you mean by type-aliases of methods. Could you elaborate?<spa=
n class=3D"m_847778784893274403gmail-im"><br>
              </span></blockquote>
            <div><br>
            </div>
            <div>Yes. So consider this:<br>
              <br>
            </div>
            <div>struct A {<br>
            </div>
            <div>=C2=A0 =C2=A0 friend void foo(A&amp;);<br>
              };<br>
              <br>
            </div>
            struct B : using A {};<br>
            <br>
          </div>
          <div>To me the only way to allow B to also have the friend
            declaration is if we could do the following transformation:<br>
            <br>
          </div>
          <div>void foo(A&amp;) ----&gt; void foo(B&amp;)<br>
          </div>
        </div>
      </div>
    </blockquote></span>
    Right.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div><br>
          </div>
          <div>In some sense creating a new foo overload using the
            type-copy. However, I believe this would be a pretty big
            change. </div>
        </div>
      </div>
    </blockquote></span>
    I believed this was already part of your proposal. (***)<span class=3D"=
"><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>If such a thing was allowed, then why stop at copies? Why
            not being able to define<br>
            <br>
          </div>
          <div>void foo(A&amp;) ----&gt; void foo(C&amp;)<br>
            <br>
          </div>
          <div>or even<br>
            <br>
          </div>
          <div>void foo(A&amp;) ----&gt; template&lt;typename T&gt; void
            foo(T&amp;);<br>
            <br>
          </div>
          <div>As this is outside of the scope of my proposal, I did not
            include this. And so, I cannot add to my proposal the
            conversion of friend and non-member function when creating a
            copy-type. If this could be included, there would be no
            problem for that.<br>
          </div>
        </div>
      </div>
    </blockquote></span>
    Sorry, I don&#39;t know yet what are type-aliases of methods.
    <span class=3D""><blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div><br>
            <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Could you ela=
borate?
              (on recursive conversion operator)<span class=3D"m_8477787848=
93274403gmail-im"><br>
              </span></blockquote>
            <div><br>
            </div>
            <div>For example, consider<br>
              <br>
            </div>
            <div>struct A {};<br>
            </div>
            <div>struct B : using A {<br>
            </div>
            <div>=C2=A0=C2=A0=C2=A0 operator A() =3D default;<br>
            </div>
            <div>};<br>
            </div>
            <div>struct C : using B {<br>
            </div>
            <div>=C2=A0=C2=A0=C2=A0 operator B() =3D default;<br>
            </div>
            <div>=C2=A0=C2=A0=C2=A0 operator A() =3D default;<br>
              };<br>
              <br>
            </div>
            <div>Just an idea.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I&#39;m lost.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div><br>
              <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=
=3D"m_847778784893274403gmail-im">
                  <blockquote type=3D"cite">
                    <div dir=3D"ltr">
                      <div>
                        <div>
                          <div>
                            <div>However, this default way to define a
                              conversion operator would be disabled if
                              the copy has added new attributes with
                              respect to its original class.<br>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </blockquote>
                </span> Why?<span class=3D"m_847778784893274403gmail-im"><b=
r>
                </span></blockquote>
              <div><br>
              </div>
              <div>I think that at that point the two classes diverged
                enough that the compiler cannot assume they can be
                converted freely? If I have:<br>
                <br>
              </div>
              <div>struct A { int x; };<br>
              </div>
              <div>struct B : using A { int y; };<br>
                <br>
              </div>
              <div>Is it really wise to allow the compiler to be able to
                default convert B to A? </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I would say, yes. The question p0109 raise is whether the user wants
    it.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>If they were the same, ok, but maybe at that point
                the user should be forced to provide a conversion
                operator, no?<br>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    If the user decides to provide the default implementation I don&#39;t
    see where the problem is.<br>
    <br>
    operator Base() =3D default;<br>
    <br>
    The compiler know how to do the conversion.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div><br>
                <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I don&#39=
;t know
                  compiler writers would like to look ahead. I believe
                  that C should be forward declared as a copy.<span class=
=3D"m_847778784893274403gmail-im"><br>
                  </span></blockquote>
                <br>
              </div>
              <div>Maybe. I thought that inherited classes are also
                declared without mentioning that they inherit, so I
                though that the same should hold for copies.<br>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Maybe, but the C++ standard doesn&#39;t have constrains on whether the
    class is derived from another class.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div><br>
                <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I will ne=
ed a
                  concrete example of when a complete hierarchy must be
                  &quot;duplicated&quot;. I&#39;m not saying there are no c=
ases, just
                  I have no one in my head.<span class=3D"m_847778784893274=
403gmail-im"></span><br>
                  <span class=3D"m_847778784893274403gmail-im"></span></blo=
ckquote>
                <br>
              </div>
              <div>I&#39;ll try to add these on the concrete examples.<br>
                <br>
                <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">You are n=
ot
                  modifying here, but adding ;-). You can say it is
                  ambiguous, but we have this case with inheritance (<a cla=
ss=3D"m_847778784893274403gmail-m_2667955782052143795moz-txt-link-freetext"=
 href=3D"http://melpon.org/wandbox/permlink/f9mRtE9n5mA9RPpl" target=3D"_bl=
ank">http://melpon.org/wandbox/per<wbr>mlink/f9mRtE9n5mA9RPpl</a>)<span cla=
ss=3D"m_847778784893274403gmail-im"></span><br>
                  <span class=3D"m_847778784893274403gmail-im"></span></blo=
ckquote>
                <br>
              </div>
              <div>Not quite, the resulting copied class would be
                equivalent to<br>
                <br>
              </div>
              <div>
                <div>struct C {<br>
                </div>
                <div>=C2=A0=C2=A0=C2=A0=C2=A0 int foo(int x) { return x * 2=
; }<br>
                  <span class=3D"m_847778784893274403gmail-im">=C2=A0=C2=A0=
=C2=A0=C2=A0 double foo(int x) { return
                    x * 2; }</span><br>
                </div>
                <div>=C2=A0=C2=A0=C2=A0=C2=A0 double bar(double x) { return=
 foo(x) * 4.0; }<br>
                  };<br>
                  <br>
                </div>
                <div>which is illegal, since you cannot overload on
                  return type. Keep in mind that there is no &quot;layer&qu=
ot;
                  between the original class and what gets added to the
                  copy.<br>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    You are right. I missed that all the function are copied. In this
    case, either a function is not copied when there is an added
    function with the same overloaded signature or the program is ill
    formed.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div><br>
                  <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I don&#=
39;t see a
                    problem here as D is a copy of A and then we are
                    defining its meaning.<br>
                    You said that it should be as simple as if defined
                    the class by hand.<span class=3D"m_847778784893274403gm=
ail-im"></span><br>
                    <span class=3D"m_847778784893274403gmail-im"></span></b=
lockquote>
                  <br>
                </div>
                <div>That&#39;s true, and that&#39;s mostly what I don&#39;=
t like
                  about giving the ability to modify copied existing
                  methods. It is definitely non-obvious that this is
                  happening. If you make a mistake, it will take a long
                  time to figure out that you involuntarily modified the
                  behavior of the original class. That&#39;s bad in my book=
..<br>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Maybe you need something like override to state clearly that you
    want to redefine the inherited behavior.<span class=3D""><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div><br>
                  <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I belie=
ve it is
                    worth mentioning it in the proposal. My
                    TBoost.Opaque library implements something like
                    that. I will start a new thread to talk about the
                    TBoost.Opaque library approach. If I need a library
                    solution for builtin types, why this library
                    solution will not work for classes, what will be the
                    added value of the language solution?<span class=3D"m_8=
47778784893274403gmail-im"></span><br>
                    <span class=3D"m_847778784893274403gmail-im"></span></b=
lockquote>
                  <br>
                </div>
                <div>I believe that wrapper types are just as good as
                  primitive types. This is also how it&#39;s always been in
                  C++. The main problem was simply that doing this over
                  and over and over was incredibly unwieldy. I don&#39;t
                  believe that the reason why the older, in-C++
                  approaches didn&#39;t work is that they were creating
                  wrappers rather than &quot;primitive type aliases&quot;. =
This
                  proposal eliminates the need for repetition as once
                  done, it is done forever. A library like boost can
                  pre-produce often used primitive types wrappers once
                  in a single header, and be done forever.<br>
                  <br>
                  <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">No p010=
9r0
                    doesn&#39;t define any operation by default (except
                    conversions). The user needs to add whatever is
                    needed, maybe using the default trampoline
                    implementation). Well this is how I understand it.<span=
 class=3D"m_847778784893274403gmail-im"></span><br>
                    <span class=3D"m_847778784893274403gmail-im"></span></b=
lockquote>
                  <br>
                </div>
                <div>From the proposal: &quot;<span style=3D"font-family:ar=
ial,helvetica,sans-serif"><font size=3D"2">Since all member functions of th=
e
                      underlying type are known to the compiler, we can
                      take advantage of this and therefore propose that
                      the compiler, </font></span><span style=3D"font-famil=
y:arial,helvetica,sans-serif"><font size=3D"2">by default, generate default=
 versions of
                      these trampolines.&quot;<br>
                    </font></span></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    </span><font size=3D"2">I interpret this as the compiler could generate=
 them
      by default, once the user has requested it using the =3D default
      syntax. I agree the proposal doesn&#39;t contain examples where this
      is clear enough.</font><br>
    <br>
    <br>
    <br>
    Vicente<br>
    <blockquote type=3D"cite"><div><div class=3D"h5">
      <div dir=3D"ltr">
        <div><span class=3D"m_847778784893274403gmail-im"></span></div>
      </div>
      <div class=3D"gmail_extra"><br>
        <div class=3D"gmail_quote">On Sat, Dec 31, 2016 at 6:15 PM,
          Vicente J. Botet Escriba <span dir=3D"ltr">&lt;<a href=3D"mailto:=
vicente.botet@wanadoo.fr" target=3D"_blank">vicente.botet@wanadoo.fr</a>&gt=
;</span>
          wrote:<br>
          <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">
            <div bgcolor=3D"#FFFFFF" text=3D"#000000"><span>
                <div class=3D"m_847778784893274403m_2667955782052143795moz-=
cite-prefix">Le
                  31/12/2016 =C3=A0 15:57, Eugenio Bargiacchi a =C3=A9crit=
=C2=A0:<br>
                </div>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>Dear Vincente,<br>
                            <br>
                          </div>
                          Thank you for your very in-depth review. I&#39;ve
                          updated the proposal using already received
                          comments from this thread, so some things have
                          changed, but it&#39;s still alright to receive
                          comments on this version. I&#39;ll explain below
                          how it has changed when answering to your
                          comments.<br>
                          <br>
                          <blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
>IIUC,
                            every occurrence of the base type in the
                            definition of the base type is replaced by
                            the new type. This is one of the options
                            described in Opaque proposal (see The return
                            type issue). Why the other alternatives have
                            less sens?<span class=3D"m_847778784893274403m_=
2667955782052143795m_-5826156030849956333gmail-im"></span><br>
                            <span class=3D"m_847778784893274403m_2667955782=
052143795m_-5826156030849956333gmail-im"></span></blockquote>
                          <span class=3D"m_847778784893274403m_266795578205=
2143795m_-5826156030849956333gmail-im">
                          </span><br>
                        </div>
                        There are many differences between my proposal
                        and the Opaque proposal. I believe that the main
                        ones that this proposal brings are:<br>
                        <br>
                      </div>
                      - Where possible, do not introduce new meanings or
                      rules to the language. The type-copied class
                      should behave as closely as possible to a class
                      the user has implemented by hand. This should make
                      very easy to understand how the feature works,
                      without the need to grasp many new concepts.<br>
                    </div>
                    - I have removed the option to modify and remove
                    existing functionality from the class that is being
                    copied. While I believe that this can be useful, it
                    introduces too much complexity in my opinion now. If
                    this is allowed, you basically have to create a
                    system where you are allowed to completely rewrite
                    an existing class starting from another, since you
                    may want to copy or remove or change anything that
                    was previously present. This I believe can both make
                    the proposal unnecessary complicated, and can make
                    the code very hard to follow, as at each new
                    strong-typedef step (since a type could be copied,
                    and the copy copied again and so on) anything could
                    happen. I now believe that an incremental-only
                    strategy (similar to inheritance) can still be both
                    useful and sufficient for most cases. Where it is
                    not, simple implementations by hand of basic
                    functionality, extended then via the type-copy
                    mechanism should result in clear, reusable code
                    which still requires little maintenance.<br>
                  </div>
                </blockquote>
              </span> To be honest, I will vote against this proposal if
              we can not modify and delete existing functionality. When
              I copy/paste a class I can change things and remove
              others.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr"><br>
                    <div>
                      <div>
                        <div>
                          <blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
>The word
                            duplicating and wrapping don&#39;t match. The
                            proposed approach doesn&#39;t wraps the
                            underlying type, except maybe for builtin
                            types.<br>
                          </blockquote>
                          <br>
                        </div>
                        <div>Right, I&#39;ll fix it, thanks.<br>
                          <br>
                          <blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
>I believe
                            the proposal needs to add some concrete
                            examples as use cases<br>
                          </blockquote>
                        </div>
                        <div><br>
                        </div>
                        <div>This makes sense, I&#39;ll worn ok an
                          additional section where I try to show some
                          concrete examples.<br>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> The best will be to add them in the motivation
              section showing how the new feature is used instead of
              some flat code.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div><br>
                          <blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
>If the
                            base class change, the strong types
                            depending on it could need maintenance also,
                            isn&#39;t it?<span class=3D"m_84777878489327440=
3m_2667955782052143795m_-5826156030849956333gmail-im"><br>
                            </span></blockquote>
                          <div><br>
                          </div>
                          <div>True, however wrapper methods have to be
                            fixed 100% of the time, while a type-copied
                            class may not need this. It&#39;s the same as i=
f
                            one modified a base class in inheritance -
                            you don&#39;t have to necessarily update all th=
e
                            code that depends on it right away.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> One of the problems of your proposal is that the
              copied class has access to the private members, which is
              more subject to changes. I believe that the copied class
              should only have access to public members.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">In
                              addition to these basic techniques, there
                              are other library solution, as e.g. using
                              CRTP that might merit to be mentioned.<br>
                              See [TBoost.Opaque] for a possible
                              implementation.<span class=3D"m_8477787848932=
74403m_2667955782052143795m_-5826156030849956333gmail-im"></span><br>
                              <span class=3D"m_847778784893274403m_26679557=
82052143795m_-5826156030849956333gmail-im"></span></blockquote>
                            <br>
                          </div>
                          <div>I&#39;ll add a mention to CRTP. I&#39;ll giv=
e a
                            look at the boost link, thanks!<br>
                            <br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">Please
                              add <a class=3D"m_847778784893274403m_2667955=
782052143795m_-5826156030849956333gmail-m_-7522649930861642754moz-txt-link-=
freetext" href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p=
0109r0.pdf" target=3D"_blank">http://www.open-std.org/jtc1/s<wbr>c22/wg21/d=
ocs/papers/2015/p010<wbr>9r0.pdf</a>
                              to this list.<span class=3D"m_847778784893274=
403m_2667955782052143795m_-5826156030849956333gmail-im"></span><br>
                              <span class=3D"m_847778784893274403m_26679557=
82052143795m_-5826156030849956333gmail-im"></span></blockquote>
                            <br>
                          </div>
                          <div>Thanks, I must have missed it.<br>
                          </div>
                          <div><br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">What is
                              wrong for you with p0109r0 approach?<br>
                              What we could have with your approach that
                              we cannot have with p0109r0?<br>
                              What we could have with p0109r0 that we
                              cannot have with your approach?<br>
                              <br>
                              IIUC, p0109r0 opaque types don&#39;t introduc=
e
                              any operations by default other than
                              conversions and your proposal introduce
                              all members but no friends<span class=3D"m_84=
7778784893274403m_2667955782052143795m_-5826156030849956333gmail-im"></span=
><br>
                              <span class=3D"m_847778784893274403m_26679557=
82052143795m_-5826156030849956333gmail-im"></span></blockquote>
                            <br>
                          </div>
                          <div>Personally, I don&#39;t think there&#39;s
                            anything &quot;wrong&quot; with p0109r0. The id=
ea for
                            this proposal came to me before I knew the
                            alternatives, but since C++ still does not
                            have strong typedefs I thought I might as
                            well propose an alternative approach, which
                            could possibly garner more interest.<br>
                            <br>
                          </div>
                          <div>I believe my approach is simpler to read
                            and more intuitive - especially when
                            creating strong aliases of very complex
                            types, but that can definitely be bias. It
                            can be applied to hierarchies of classes,
                            since it allows type-copying interdependent
                            classes, which I believe is very important.
                            It is very easy to use with templates and
                            specializations, which potentially gives it
                            a lot of power and very many potential uses.
                            It is easily composable, as in copying a
                            copy is very easy and indeed expected in my
                            view for the feature.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> You will need to show how all this arguments
              applies on concrete examples and how p0109r0 could do the
              same thing.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                          </div>
                          <div>With p0109r0 there&#39;s more flexibility to
                            alter a type. The additional flexibility
                            allows it to take on more tasks, as in
                            type-copying friends, since default ways to
                            convert to the original types exist. It is
                            designed for primitive types first, while I
                            have actually removed them in my last
                            iteration for a number of reasons (see
                            below). </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> Again, I will vote against this proposal if it
              doesn&#39;t provides a solution for builtin types, as this is
              IMHO one of the most appealing use cases.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>The additional flexibility however comes
                            at a cost, as you mention the return type
                            issue, which my proposal does not have.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> Your proposal has already this issue as you copy
              the whole class, and so you replace every occurrence of
              the base class with the new class.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                          </div>
                          <div>I don&#39;t introduce friends mostly because
                            a feature to create type-aliases of methods
                            does not currently exist, </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> I don&#39;t know what do you mean by type-aliases of
              methods. Could you elaborate?<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>and I don&#39;t believe it is wise to add it
                            to the scope of this proposal since it would
                            be another very large change. If such a
                            feature existed, however, adding friends to
                            a type-copied class in my proposal would be
                            trivial, as simply strong typedefs of the
                            needed functions could be created on the
                            fly. The same could also be done for
                            non-member functions if needed, but how that
                            would work I have not thought about yet.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> Could you elaborate how type-aliases of methods
              would help here?<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">I find
                              that conversions to/from the underlying
                              type must be covered by the proposal. If
                              we change the Base type we don&#39;t want to
                              be forced to redefine the conversion
                              operator.<br>
                              Maybe we need some kind of default
                              conversion implementation<br>
                              <span style=3D"font-family:courier new,monosp=
ace">=C2=A0=C2=A0=C2=A0 operator Base() <b>=3D
                                  default</b>;</span><br>
                              <span style=3D"font-family:courier new,monosp=
ace"> or </span><br>
                              <span style=3D"font-family:courier new,monosp=
ace">=C2=A0=C2=A0=C2=A0 <b>explicit</b>
                                operator Base() <b>=3D default</b>;</span><=
br>
                            </blockquote>
                          </div>
                          <div><br>
                          </div>
                          <div>I like this. I didn&#39;t add it to keep the
                            number of features as low as reasonably
                            possible, but this is simple enough. This
                            could also be used recursively, as in a copy
                            of a copy could define a conversion operator
                            to both the first copy and the original in
                            this way. </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> Could you elaborate?<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>However, this default way to define a
                            conversion operator would be disabled if the
                            copy has added new attributes with respect
                            to its original class.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> Why?<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">Why do
                              you introduce this restriction? (on
                              template parameter numbers)<br>
                            </blockquote>
                          </div>
                          <div><br>
                          </div>
                          <div>No actually, you&#39;re right. I should lift
                            it. I thought initially that there wouldn&#39;t
                            be any reason to add more template
                            parameters, as they would only be needed to
                            satisfy the original class. But this is
                            definitely wrong. I&#39;ll change it, thanks.<b=
r>
                          </div>
                          <div><br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">In **
                              above C has not yet defined as a copy<span cl=
ass=3D"m_847778784893274403m_2667955782052143795m_-5826156030849956333gmail=
-im"></span><br>
                              <span class=3D"m_847778784893274403m_26679557=
82052143795m_-5826156030849956333gmail-im"></span></blockquote>
                            <br>
                          </div>
                          <div>Ill explain how I believe this example
                            should work. Since C has been declared but
                            not defined when parsing D, the compiler
                            will be allowed to assume that C is going to
                            be defined later as a type-copy of A. If
                            that does not happen, then the compiler will
                            give an error, either at the definition of C
                            or of D, explaining that D assumed that C
                            would have been a type-copy while it was
                            not. If C has added new attributes to its
                            declaration though D&#39;s definition would nee=
d
                            to take the new size of C into account
                            though. Not sure if this can be done or if
                            it should result in an error.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> I don&#39;t know compiler writers would like to look
              ahead. I believe that C should be forward declared as a
              copy.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">I
                              believe this interdependent case introduce
                              a lot of complexity. We would need a good
                              use case to introduce it on the standard.<spa=
n class=3D"m_847778784893274403m_2667955782052143795m_-5826156030849956333g=
mail-im"></span><br>
                              <span class=3D"m_847778784893274403m_26679557=
82052143795m_-5826156030849956333gmail-im"></span></blockquote>
                            <br>
                          </div>
                          <div>A very simple example would be copying of
                            inherited classes, both base and derived.
                            Without a way to do this that just cannot be
                            done. This can be important if one does not
                            want that the derived type and its type-copy
                            are allowed to be converted to the same
                            base. This is a strong reason, I believe,
                            otherwise strong-typing in that case just
                            lost some power in keeping original and
                            type-copy apart.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> I will need a concrete example of when a complete
              hierarchy must be &quot;duplicated&quot;. I&#39;m not saying =
there are
              no cases, just I have no one in my head.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">I
                              believe that this cannot be optional as in
                              a lot of cases we need to modify/restrict
                              the base type interface.<br>
                            </blockquote>
                            <br>
                          </div>
                          <div>I have actually removed this in my newest
                            revision. I believe that ground-up building
                            of types is the better way to go (as is
                            normally done in inheritance). Having the
                            power to completely alter the original type,
                            possibly to a point where there was not even
                            much in common between the original and the
                            type-copy, is not worth it. This is a
                            personal opinion, but I believe doing so can
                            prevent some very complex and ugly code
                            smells, at a not incredible cost.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> We need to solve concrete problems. The 1st use
              case I have for strongly types is to reduce the interface
              provided by the underlying type and to adapt the functions
              signatures to the new class.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                          </div>
                          <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>Could you give a concrete example of
                              this kind of problems?<br>
                            </div>
                          </blockquote>
                          <div>
                            <div style=3D"margin-left:40px"><span class=3D"=
m_847778784893274403m_2667955782052143795m_-5826156030849956333gmail-im"></=
span></div>
                            <br>
                          </div>
                          <div>Suppose<br>
                            <br>
                          </div>
                          <div>struct A {<br>
                          </div>
                          <div>=C2=A0=C2=A0=C2=A0=C2=A0 int foo(int x) { re=
turn x * 2; }<br>
                          </div>
                          <div>=C2=A0=C2=A0=C2=A0=C2=A0 double bar(double x=
) { return foo(x)
                            * 4.0; }<br>
                            };<br>
                          </div>
                          <div><br>
                          </div>
                          <div>struct B : using A {<br>
                          </div>
                          <div>=C2=A0=C2=A0=C2=A0 int foo(int) =3D delete;<=
br>
                          </div>
                          <div>=C2=A0=C2=A0=C2=A0 // bar cannot compile any=
more<br>
                          </div>
                          <div>};<br>
                            <br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> Where is the problem? struct B will not compile.
              That&#39;s all.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>struct C : using A {<br>
                          </div>
                          <div>=C2=A0=C2=A0=C2=A0 double foo(int x) { retur=
n x * 2; }<br>
                          </div>
                          <div>=C2=A0=C2=A0=C2=A0 // ambiguous definition<b=
r>
                            };<br>
                          </div>
                          <div><br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> You are not modifying here, but adding ;-). You
              can say it is ambiguous, but we have this case with
              inheritance (<a class=3D"m_847778784893274403m_26679557820521=
43795moz-txt-link-freetext" href=3D"http://melpon.org/wandbox/permlink/f9mR=
tE9n5mA9RPpl" target=3D"_blank">http://melpon.org/wandbox/per<wbr>mlink/f9m=
RtE9n5mA9RPpl</a>)<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>struct D : using A {<br>
                          </div>
                          <div>=C2=A0=C2=A0=C2=A0 double foo(double x) { re=
turn x * 3;
                            }<br>
                          </div>
                          <div>=C2=A0=C2=A0=C2=A0 // Changes meaning of bar
                            underhandedly with no warning<br>
                          </div>
                          <div>};<br>
                            <br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> I don&#39;t see a problem here as D is a copy of A an=
d
              then we are defining its meaning.<br>
              You said that it should be as simple as if defined the
              class by hand.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>I suppose even more dangerous and complex
                            cases could be devised.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> We will need some real examples to see how
              dangerous they are ;-)<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div><br>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">While
                              this is inline with your approach, this
                              merits some explanations as the operators
                              are no members. Shouldn&#39;t the operators o=
f
                              UDT classes meritt to be inherited as
                              well?<br>
                            </blockquote>
                            <div><br>
                            </div>
                            <div>I&#39;ve removed primitive type support
                              also for this reason. They are not
                              currently treated as classes by C++, and
                              so I think I shouldn&#39;t either. Instead my
                              approach is now constructive. If one
                              needed aliases for primitive types, one
                              could create a single header of wrappers
                              in the form<br>
                              <br>
                            </div>
                            <div>template &lt;typename T&gt;<br>
                            </div>
                            <div>class SimpleWrapper {<br>
                            </div>
                            <div>=C2=A0=C2=A0=C2=A0 public:<br>
                            </div>
                            <div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 SimpleWrapper(T t) : t_(t) {}<br>
                              <br>
                            </div>
                            <div>=C2=A0=C2=A0=C2=A0 private:<br>
                            </div>
                            <div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 T t_;<br>
                            </div>
                            <div>};<br>
                              <br>
                            </div>
                            <div>template &lt;typename T&gt;<br>
                            </div>
                            <div>struct SimpleWrapperWithSum : using
                              SimpleWrapper&lt;T&gt; {<br>
                            </div>
                            <div>=C2=A0=C2=A0=C2=A0 SimpleWrapperWithSum
                              operator+(const SimpleWrapperWithSum &amp;
                              other) { return t_ + other.t_; }<br>
                            </div>
                            <div>};<br>
                              <br>
                            </div>
                            <div>And so on. It would only be needed
                              once, and then users could simply copy the
                              versions with the operators they need to
                              use. It&#39;s not incredibly pretty and it
                              does have some limitations, but it works,
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> I believe it is worth mentioning it in the
              proposal. My TBoost.Opaque library implements something
              like that. I will start a new thread to talk about the
              TBoost.Opaque library approach. If I need a library
              solution for builtin types, why this library solution will
              not work for classes, what will be the added value of the
              language solution?<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>
                            <div>and in any case even in p0109r0 one
                              would need to remove all unneeded
                              operators, so work would need to be done
                              anyway. <br>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> No p0109r0 doesn&#39;t define any operation by defaul=
t
              (except conversions). The user needs to add whatever is
              needed, maybe using the default trampoline
              implementation). Well this is how I understand it.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>
                            <div><br>
                            </div>
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">
                              <div>I believed that there where no
                                implicit conversions on your proposals.
                                How (*this) is converted to an int?<br>
                                <br>
                                What would be the result type of x
                                below?<br>
                                <br>
                                Id id(1);<br>
                                auto x =3D +id;<br>
                                <br>
                                I suspect that it would be Id.<span class=
=3D"m_847778784893274403m_2667955782052143795m_-5826156030849956333gmail-im=
"></span><br>
                              </div>
                            </blockquote>
                            <div>
                              <blockquote><span class=3D"m_8477787848932744=
03m_2667955782052143795m_-5826156030849956333gmail-im"></span></blockquote>
                              Yeah, this was a weird syntax, I thought
                              it could be a simple way to represent
                              conversion to the underlying primitive
                              type.<br>
                              <br>
                              The type of the operation would be Id,
                              yes. I believe that to be the only
                              intuitive result that makes sense, unless
                              an explicit operator+ that does a
                              conversion has been defined somewhere. If
                              a cast is needed, one needs to cast. I
                              don&#39;t see a reason to change that for
                              strong typedefs, otherwise the language
                              would be inconsistent IMO.<br>
                              <br>
                              <blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex">Why
                                this restriction is needed or desirable.<sp=
an class=3D"m_847778784893274403m_2667955782052143795m_-5826156030849956333=
gmail-im"> (w.r.t.
                                  final in type-copies of primitive
                                  types)<br>
                                </span></blockquote>
                              <div><br>
                              </div>
                              <div>It is not. But I believe that if one
                                needs to do something, it has to be in
                                line with the rest of the language. If a
                                strong typedef of a primitive type is
                                needed, it would still need to follow
                                the rules of primitive types. </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> It depends. If a strong type is able to define new
              members it is not anymore a builtin and becomes for me a
              class.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>
                            <div>
                              <div>As primitive types are not
                                inheritable, I believe neither should
                                the strong typedefs. Maybe this is a
                                wrong position, I don&#39;t know (since
                                primitive typedefs are not inheritable
                                due to C compatibilities IIUC), but I
                                believe that having consistency is still
                                useful for a proposal. Otherwise one
                                needs to always learn a million
                                exceptions to each rule, and that I
                                don&#39;t like, where it can be avoided. In
                                any case, these are my opinions, but if
                                there is strong consensus to change how
                                the proposal works I have no problem in
                                modifying it.<br>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> You need to justify your decisions on a rationale
              section. But as you have removed builtin types as base
              types this is not needed anymore. You will need to justify
              why builtin are not supported :(=C2=A0 <br>
              <span>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>
                            <div>
                              <div><br>
                                <blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex">Example
                                  of where this can be useful welcome.<br>
                                </blockquote>
                                <div><br>
                                </div>
                                <div>I must admit I didn&#39;t really think
                                  about this, I just thought they could
                                  be nice to have. Maybe they would be
                                  useless. I just considered that
                                  sometimes the ingenuity of how people
                                  use tools always seem to surprise, so
                                  why not. Maybe in order to SFINAE the
                                  generation of conversion operators to
                                  classes, given that they are copies of
                                  the original? Something like<br>
                                  <br>
                                </div>
                                <div>struct Copy : using A {<br>
                                </div>
                                <div>=C2=A0=C2=A0=C2=A0=C2=A0 template &lt;=
typename T, /*
                                  enable_if_t&lt;is_copy_of_v&lt;T,
                                  A&gt;&gt;&gt; */&gt;<br>
                                </div>
                                <div>=C2=A0=C2=A0=C2=A0=C2=A0 operator T =
=3D default;<br>
                                </div>
                                <div>};<br>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> Features must be added to solve concrete problems.<br=
>
              <br>
              I suggest you to work on the motivation section with real
              concrete examples.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>
                            <div>
                              <div>
                                <div><br>
                                  <blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex">How
                                    other type traits behave for the
                                    copied class (see p0109r0)?<br>
                                  </blockquote>
                                  <br>
                                </div>
                                <div>All other type traits behave as if
                                  the class had been implemented by
                                  hand, and is separate from the
                                  original. so is_same would return
                                  false, for example. It seems that
                                  p0109r0 thinks the same way. The only
                                  difference is that sizeof may be
                                  different, since in my proposal one
                                  could add additional attributes to the
                                  type-copied class. (There&#39;s no
                                  examples in the old version, I&#39;ve
                                  added them on GitHub though).<br>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> I agree for is_same of course. I was wondering for
              other traits that could have been specialized for the base
              class. I suspect the answer is that the user would need to
              specialize the new type again.<span><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>
                      <div>
                        <div>
                          <div>
                            <div>
                              <div>
                                <div><br>
                                </div>
                                <div>Thanks again for your feedback.<br>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </span> You are welcome,<br>
              Vicente<br>
              <br>
            </div>
            <span>
              -- <br>
              You received this message because you are subscribed to a
              topic in the Google Groups &quot;ISO C++ Standard - Future
              Proposals&quot; group.<br>
              To unsubscribe from this topic, visit <a href=3D"https://grou=
ps.google.com/a/isocpp.org/d/topic/std-proposals/gkJUVnL-Fmg/unsubscribe" t=
arget=3D"_blank">https://groups.google.com/a/is<wbr>ocpp.org/d/topic/std-pr=
oposals<wbr>/gkJUVnL-Fmg/unsubscribe</a>.<br>
              To unsubscribe from this group and all its topics, send an
              email to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.o=
rg" target=3D"_blank">std-proposals+unsubscribe@isoc<wbr>pp.org</a>.<br>
              To post to this group, send email to <a href=3D"mailto:std-pr=
oposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
            </span>
            To view this discussion on the web visit <a href=3D"https://gro=
ups.google.com/a/isocpp.org/d/msgid/std-proposals/f4a57116-c65b-94f4-51f2-e=
5cf8b4ff3ca%40wanadoo.fr?utm_medium=3Demail&amp;utm_source=3Dfooter" target=
=3D"_blank">https://groups.google.com/a/is<wbr>ocpp.org/d/msgid/std-proposa=
ls<wbr>/f4a57116-c65b-94f4-51f2-<wbr>e5cf8b4ff3ca%40wanadoo.fr</a>.<br>
          </blockquote>
        </div>
        <br>
      </div>
      -- <br></div></div><span class=3D"">
      You received this message because you are subscribed to the Google
      Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br></sp=
an>
      To unsubscribe from this group and stop receiving emails from it,
      send an email to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.o=
rg" target=3D"_blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<span c=
lass=3D""><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.go=
ogle.com/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2BtVBKZOMtpURNBDCEJijF=
L_J5s%2BROrLwJfkRgGyWzZMgg%40mail.gmail.com?utm_medium=3Demail&amp;utm_sour=
ce=3Dfooter" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/=
d/msgid/std-<wbr>proposals/CAHfn%3D%<wbr>2BtVBKZOMtpURNBDCEJijFL_J5s%<wbr>2=
BROrLwJfkRgGyWzZMgg%40mail.<wbr>gmail.com</a>.<br>
    </blockquote>
    <p><br>
    </p>
  </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/gkJUVnL-Fmg/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/<wbr>isocpp.org/d/topic/std-<wbr>proposals/g=
kJUVnL-Fmg/<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/ef8190c7-f46f-cf76-7e45-2114a84eae27%=
40wanadoo.fr?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/ef81=
90c7-f46f-cf76-<wbr>7e45-2114a84eae27%40wanadoo.fr</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%2BtEbHpzdtK40qS_tVUPfPyKnOft=
-ZXOTMTDezPDzS3fAw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2BtE=
bHpzdtK40qS_tVUPfPyKnOft-ZXOTMTDezPDzS3fAw%40mail.gmail.com</a>.<br />

--94eb2c03c7908d1bfd05450bbbd4--

.
