220 30154 <CAHfn=+vZEjYakroOWxB8u+SCS=5uDGU5mdYpWpyCbD-qS-P3TQ@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: Mon, 2 Jan 2017 13:31:32 +0100
Lines: 2042
Approved: news@gmane.org
Message-ID: <CAHfn=+vZEjYakroOWxB8u+SCS=5uDGU5mdYpWpyCbD-qS-P3TQ@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> <CAHfn=+tEbHpzdtK40qS_tVUPfPyKnOft-ZXOTMTDezPDzS3fAw@mail.gmail.com>
 <9adc5a02-3209-bf63-a684-fb0272da56e0@wanadoo.fr>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=001a113dc5885ce22c05451bbbab
X-Trace: blaine.gmane.org 1483360305 16492 195.159.176.226 (2 Jan 2017 12:31:45 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 2 Jan 2017 12:31:45 +0000 (UTC)
To: "ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCWJHLVBTMARBJUQVHBQKGQE5SL3RVY@isocpp.org Mon Jan 02 13:31:37 2017
Return-path: <std-proposals+bncBCWJHLVBTMARBJUQVHBQKGQE5SL3RVY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ua0-f198.google.com ([209.85.217.198])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCWJHLVBTMARBJUQVHBQKGQE5SL3RVY@isocpp.org>)
	id 1cO1lz-0002gx-M3
	for gclcip-std-proposals@m.gmane.org; Mon, 02 Jan 2017 13:31:32 +0100
Original-Received: by mail-ua0-f198.google.com with SMTP id 34sf487945484uac.6
        for <gclcip-std-proposals@m.gmane.org>; Mon, 02 Jan 2017 04:31:35 -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=4zLTfy/vcpxBQM3DNB6bFJXpi3D6cEwCMx31MTXPZpg=;
        b=veWvYz/QCWUpgPr0TYQPwf7ypDcRqfkiNh1AFgCQIoWGB0Gi3PByL5HMU07H4VOzMt
         gB78p5ne2Frq345W8XtSoZv6zSiEtOka1f+BfnQO/5ogjWdNcvFm/CkJjMtfaKpdvdZy
         T2DxqgLsTT8LCfS4hMrXAZkLDojjynoM7KSYZkAffiXcYgtf46Fikj3TCpXARSaYOtGX
         6OY97bUT6fYFtLdN31AGk2vp/NhQY/TP5B24r2NV1F8vNQpEl8hFBXcr4tTQqoU+x7Rv
         2j7QQ0EgPeESWgvfmJZsXBJsjMqcWW95c0UVgKWwLk0XTrXWvo1OxtAVSXd/dVzLVH8F
         3NRQ==
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=4zLTfy/vcpxBQM3DNB6bFJXpi3D6cEwCMx31MTXPZpg=;
        b=OjzaBSeVeKK9qMB2bWYHzNqnB2vORRr524NZktNhxoquHp4nH+6MmHqoOCKkfHSygp
         zJ+2P2VeOeK53X6S+DbEe+nZN6rsvGoufnx6JF0/A8Vbi2WXiEdF1/RCNSlkWvj1ZT0s
         lCaIheqhuwu9hS7KuemCJkJSQ03qvobHegZ6OSXnrBf0FV0pBVv2hTnxUT6Dh7ekwFIy
         7+D3MQn0HvChBs+DE2Yu6xoWu1r8c34nMZ2VG2NGk7vQz2gYxUUokFeQloUJwdT4dASu
         KbzhQp8P+jYgeCRg0kT2UzxyX8jTxsWl1CBkVLF+q7S0PdfCS+ptEpf5iAQSY5f8DhV/
         NMfg==
X-Gm-Message-State: AIkVDXJBVKprNO+Bnl8qBikaqkW4/WcKZHFr/3E0UmqkDJXe4nTofZvsO9RjA+XNsn6ZeQ==
X-Received: by 10.31.50.77 with SMTP id y74mr10800016vky.7.1483360295112;
        Mon, 02 Jan 2017 04:31:35 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.52.171 with SMTP id g40ls40871066otc.47.gmail; Mon, 02 Jan
 2017 04:31:34 -0800 (PST)
X-Received: by 10.176.7.196 with SMTP id d4mr36738815uaf.171.1483360294111;
        Mon, 02 Jan 2017 04:31:34 -0800 (PST)
Original-Received: from mail-vk0-x22b.google.com (mail-vk0-x22b.google.com. [2607:f8b0:400c:c05::22b])
        by mx.google.com with ESMTPS id r6si12108080uar.190.2017.01.02.04.31.34
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Mon, 02 Jan 2017 04:31:34 -0800 (PST)
Received-SPF: pass (google.com: domain of svalorzen@gmail.com designates 2607:f8b0:400c:c05::22b as permitted sender) client-ip=2607:f8b0:400c:c05::22b;
Original-Received: by mail-vk0-x22b.google.com with SMTP id p9so263362551vkd.3
        for <std-proposals@isocpp.org>; Mon, 02 Jan 2017 04:31:34 -0800 (PST)
X-Received: by 10.31.1.215 with SMTP id 206mr20784606vkb.126.1483360293411;
 Mon, 02 Jan 2017 04:31:33 -0800 (PST)
Original-Received: by 10.31.227.133 with HTTP; Mon, 2 Jan 2017 04:31:32 -0800 (PST)
In-Reply-To: <9adc5a02-3209-bf63-a684-fb0272da56e0@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:c05::22b 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:30154
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/30154>

--001a113dc5885ce22c05451bbbab
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Dear Vicente,

Eugenio, I believe the use cases we have both in mind are quite different,
> and so we don't reach to understand one to each other.


It seems so. I am available to try other forms of communications if you
want (chat, voice call) if you want. I'm sorry I'm not being as clear as I
want.

I have a question. Does you copy class proposal needs to have the
> definition of the copied class available?
> If yes, I don't think this could be acceptable.
> If the declaration is enough, the copied functions would need at least an
> internal conversion to/from the underlying type, isn't it?
>

My proposal does not need the definition. Yes, I suppose an internal
conversion would be needed. The internal conversion would probably work
similarly to how inheritance works, even if adding non-static members was
allowed. As in, the compiler knows that the first piece of the class will
be the same as the original, and every new member is added at the end.

> B b;
> b.A::bar(5);
>
> Agreed. And the language let me do that even if you find it could be bad
> practice. I don't see why your copy approach wouldn't let me do that.
>

In my approach the old function is impossible to hide, so I think that the
two cases are different.

> 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.
>
> You are probably right, and the copy should copy every thing and give
> access to everything internally. I need some concrete examples to
> understand what this possibility will solve.
>

Well, for example, a library that wanted to create strong typedefs of
primitive types via wrappers and only expose certain operations, without
getters/setters ;) I've added some code later to show you how a possible
implementation using this proposal.

> 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.
>
> I wouldn't say hiding, just don't looking inside the underlying type. I
> want to provide access to it (when needed) but only as a whole.
>
> Possibly adding more public methods only using the public interface, whic=
h
> 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 norm=
al
> C++ facilities, since every juicy bit is hidden.
>
> Why it is unusable? The class provide access to everything you want.
>

Classes don't always come with getters and setters for every private field.
Especially if the interface they provide is a high level one. It happens
often in low-level code that you want to interact with the underlying bits
in very specific ways, but you don't necessarily want to give that kind of
access to users. So creating a strong typedef of such a class while adding
a new mode of operation would be impossible, as the copy won't have access
to the underlying implementation.

Another could be when you have to types that you know contain the same
(private) data, but should expose different public interfaces. Then you
could first create the class containing the data, and copy it two times,
each time exposing a different interface (which would need access to the
private data). Once again, I unfortunately don't have a practical use case
at the moment. I just think it could be useful.

Still the code below is a good use-case I think, since it would be needed
to provide strong typedefs of primitive types.

> Applying strong-typing again to a strong-typed class would be useless as
> access to internals would be the same,
>
> You can strong-type again. I don't see the trouble. E.g; you can have a
> energy strong-type and have kinetic_energy, potential_energy and
> heat_energy strong-type of energy.
> Typing and representation are two different things. Strong types are just
> that. Share a representation and have different types.
>

Yes, of course. What I mean is, you have created a class which can only
create exact copies of it. If you need additional changes, it will probably
be easier to strong-type the original again and create new trampolines from
that. This is what I mean by non-extendable.

> aside from possibly adding more data (if needed) in the public attributes=
,
> since only those are editable. This would also prevent encapsulation of n=
ew
> data. If not, it would just mean that the feature wouldn't be used in a
> composable way.
>
> I believe now that strong-type shouldn't add any new non-static data memb=
er


I start to see what you mean. But still, if one could add them, the copy
would still "contain" an equivalent of the original class at its beginning.
It wouldn't be guaranteed reinterpret_cast-able, but the fields would be
there anyway. The original representation is there - so to me it could
still be considered a strong-typedef (stretching a bit the definition
maybe).

Is there any other reason why you don't like the idea?

> A feature that creates a non-extendable object is like a dead-end.
>
> I must agree with your last sentence, but I don't think the strong-types
> I'm suggesting are non-extendable?
>

Well, if only the public interface is available, than adding new methods to
it is pretty much equivalent with creating non-member functions (since
those work with public interface). Then you might as well remove the
ability to add new member functions, since non-members will do just fine
and there's no need to have them as members.

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 need=
s
> to be made once (and if not needed by someone, not used).
>
> We need some probe of concept applied to concrete examples we want to
> solve. I believe a strong type feature must solve the builtin type case. =
If
> your proposal is not a strong type proposal, then forget my comments.
>

This is how I would practically solve the primitive types problem using my
proposal:

------------------------------------------

// library.hpp

template <typename T>
class Wrap {
    public:
        using base_type =3D T;

        Wrap(const Wrap & other) : t_(other.t_) {}
        explicit Wrap(T t) : t_(t) {}

    private:
        T t_;
};

template <typename C>
class ConvertBack : using C {
    operator base_type() { return t_; }
};

template <typename C>
class Plus : using C {
    Plus operator+(Plus other) { return Plus{t_ + other.t_}; }
};

template <typename C>
class Minus : using C {
    Minus operator-(Minus other) { return Minus{t_ - other.t_}; }
};

template <typename C>
class Prod : using C {
    Prod operator+(Prod other) { return Prod{t_ * other.t_}; }
};

template <typename C>
class Div : using C {
    Div operator/(Div other) { return Div{t_ / other.t_}; }
};

template <typename T>
using Arithmetic =3D Div<Prod<Minus<Plus<Wrap<T>>>>>;

// .... and so on

// usercode.cpp

#include "library.hpp"

// Strong typedef of int with +,-,/,*
struct MyInt : using Arithmetic<int> {}

// Strong typedef of double with +,- convertible to double
struct MyDouble : using ConvertBack<Minus<Plus<Wrap<double>>>> {}

--------------------------------------------

If there's something missing you'd like to see how I'd do, let me know. Of
course verbosity depends on granularity. If all operations need to be
manually selected you'll have lots of classes. If the granularity required
is less each class could add more operators at once.

Note that you need access to privates to be able to do this, so this could
be an use-case for that.

A problem that is not tackled in this code and that we are also discussing
is what to do with non-member functions (that could possibly take base_type
as input). That depends on how non-member functions will be handled in the
proposals. If they can be handled I would actually be happier.

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 o=
wn.
>
> How then you will be able to construct a B from a A if B adds more
> non-static data members?
>

One option is to simply define a constructor in B which takes A. Otherwise,
it would be the same case when you create a class with a member which the
constructor does not initialize. Otherwise one exception could be made for
constructors so that they can be redefined in the new class. This probably
makes sense and it shoudn't be possible to break something (unless one
creates a constructor which does not initialize some fields which are
assumed initialized by the original class.. but then I believe it's a
reasonable risk).

As you want to inherit all the member functions from the underlying class,
> it has a sens to concentrate on member functions. I don't understand why
> friend functions could not follow the same schema.
>

Well, friend functions are not members, so if you allow copying them, you
are allowing copying arbitrary non-member functions (which I approve of).
The only problem with this is that it is a big change - on top of this
proposal. Just that.

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.
>
> I believe I understand you now but I don't see how this could help.
>

Well, this would be the way to create the "trampolines" for non-member
functions. When you copy a class, you specify just once from which class
you are copying. The compiler can then apply the change to all member
functions automatically.

However, you still have to specify non-member functions manually, since the
compiler cannot assume you want them all.

and also to A (since C is a type-copy of a type-copy).
>
> The first Opaque proposal contained a implicit subsumption relation that
> allowed that. I'm all for, but I believe the committee doesn't like
> transitivity in conversions.
>

Well, it is not really transitivity. As in, the C to A transition does not
need an implicit transition from B. The user is explicitly creating the
conversion operator. The data in C exists, so it can be copied directly.
Maybe you mean transitivity in the sense that the compiler needs to
remember that C is a copy of B in order for it to know that it is also a
copy of A. In that case I agree.

In any case, I don't think it is really necessary, it was just an idea.

Best,
Eugenio Bargiacchi

On Mon, Jan 2, 2017 at 12:30 AM, Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr> wrote:

> Le 01/01/2017 =C3=A0 18:26, Eugenio Bargiacchi a =C3=A9crit :
>
> Eugenio, I believe the use cases we have both in mind are quite different=
,
> and so we don't reach to understand one to each other.
>
> I have a question. Does you copy class proposal needs to have the
> definition of the copied class available?
> If yes, I don't think this could be acceptable.
> If the declaration is enough, the copied functions would need at least an
> internal conversion to/from the underlying type, isn't it?
>
>
> 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 encapsulat=
ed
> data. With public inheritance, you did not make that member not accessibl=
e.
> It is still so, you have just hidden it.
>
> B b;
> b.A::bar(5);
>
> Agreed. And the language let me do that even if you find it could be bad
> practice. I don't see why your copy approach wouldn't let me do that.
>
> 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 tha=
t
>>> the copied class should only have access to public members.
>>
>>
>> If one creates a new class, and private members cannot be accessed, ther=
e
>> 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
>> take 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 anothe=
r
> class, with the ability to alter and access its public interface only. Wh=
at
> happens when you delete a public method used by a private method?
>
> Compile error ?
>
> What happens when you delete a public attribute used in private code?
>
> We can not remove data members, otherwise we can not share the same
> representation.
>
> What happens to protected code - if not accessible you basically make
> inheritance useless on it?
>
> Good question. With the wrapping approach, you couldn't inherit from it.
> With you approach, the data will be copied. The question is if the
> strong-type has access to this protected data.
> I have never needed to create a duplicate of a class that is part of
> inheritance hierarchy. I've always wrapped final classes. Some examples
> will help me to clarify the need.
> I believe we could have duplication having access only to the public part
> and let the derived classes use the protected part. Nevertheless I could
> live providing access to the protected part.
>
> 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.
>
> You are probably right, and the copy should copy every thing and give
> access to everything internally. I need some concrete examples to
> understand what this possibility will solve.
>
>
> I feel that what you are proposing is basically a fast way to create PIMP=
L
> wrappers.
>
> Not at all.
>
> 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.
>
> I wouldn't say hiding, just don't looking inside the underlying type. I
> want to provide access to it (when needed) but only as a whole.
>
> Possibly adding more public methods only using the public interface, whic=
h
> 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 norm=
al
> C++ facilities, since every juicy bit is hidden.
>
> Why it is unusable? The class provide access to everything you want.
>
> Applying inheritance to it would require manual exposure of all methods,
> with the limitations we have already discussed.
>
> I don't follow you here.
>
> Applying strong-typing again to a strong-typed class would be useless as
> access to internals would be the same,
>
> You can strong-type again. I don't see the trouble. E.g; you can have a
> energy strong-type and have kinetic_energy, potential_energy and
> heat_energy strong-type of energy.
> Typing and representation are two different things. Strong types are just
> that. Share a representation and have different types.
>
> aside from possibly adding more data (if needed) in the public attributes=
,
> since only those are editable. This would also prevent encapsulation of n=
ew
> data. If not, it would just mean that the feature wouldn't be used in a
> composable way.
>
> I believe now that strong-type shouldn't add any new non-static data
> member.
>
>
> 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 th=
at
> 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 i=
t
> 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 par=
ts
> can be combined in many possible ways. A feature that creates a
> non-extendable object is like a dead-end.
>
> I must agree with your last sentence, but I don't think the strong-types
> I'm suggesting are non-extendable?
>
>
> 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.
>>
>
> 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).
>
> We need some probe of concept applied to concrete examples we want to
> solve. I believe a strong type feature must solve the builtin type case. =
If
> your proposal is not a strong type proposal, then forget my comments.
>
> 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 (us=
ing
>> 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 compi=
ler
>> to generate the default trampolines. This is much sorter than defining t=
hem
>> using the current C++ language. Implicit conversions (public) allow to u=
se
>> 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?
>
> I believe we are not understanding one each other. My two last paragraphs
> don't concern your proposal. It concerns p0109.
>
>
> 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
>> data members. Otherwise I don't see how the duplication of such function
>> can be 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&);
> };
>
> Great.
>
> Forcing the user to inherit to add more data adds inheritance, which mean=
s
> 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 o=
wn.
>
> How then you will be able to construct a B from a A if B adds more
> non-static data members?
>
>
> 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.
>
> Do you mean for member functions?
>
> 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 wide=
r.
> 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 you want to inherit all the member functions from the underlying class=
,
> it has a sens to concentrate on member functions. I don't understand why
> friend functions could not follow the same schema.
>
> 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-mem=
ber
>> function when creating a copy-type. If this could be included, there wou=
ld
>> 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 b=
e
> 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 som=
e
> 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.
>
> I believe I understand you now but I don't see how this could help.
>
> 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?
>
> 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),
>
> Right
>
> and also to A (since C is a type-copy of a type-copy).
>
> The first Opaque proposal contained a implicit subsumption relation that
> allowed that. I'm all for, but I believe the committee doesn't like
> transitivity in conversions.
>
>
> 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.
>>
>
> I'm not sure, however to me there's no difference either way.
>
> The compiler is always able to do the conversion and the user defines whe=
n
> the compiler will do it.
>
>
> 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 class=
es
> that are not necessarily copies of the originals, as long as their
> interface is compatible to what it needs to be)
>
> Maybe.
>
> 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 thi=
s
>> 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=
'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 a=
nd
> work, nothing is being redefined. Simply the old function would get linke=
d
> against the new implementation. There's nothing that the compiler could d=
o
> to prevent this.
>
> Well, this is your proposal, and if you don't want to be able to modify
> the duplicate class, you are then right. But if you where able to modify
> the duplicated class, overriden could have a sense, to mean replace it.
>
>
> Best,
> Eugenio
>
> 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/9adc5a02-3209-bf63-a684-
> fb0272da56e0%40wanadoo.fr
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9adc5a02-32=
09-bf63-a684-fb0272da56e0%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%2BvZEjYakroOWxB8u%2BSCS%3D5uDGU5mdYpWpy=
CbD-qS-P3TQ%40mail.gmail.com.

--001a113dc5885ce22c05451bbbab
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, I believe the use cases we have both in mind are quit=
e
    different, and so we don&#39;t reach to understand one to each other.</=
blockquote><div><br></div><div>It seems so. I am available to try other for=
ms of communications if you want (chat, voice call) if you want. I&#39;m so=
rry I&#39;m not being as clear as I want.<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 have a question. Does you copy class proposal nee=
ds to have the
    definition of the copied class available?<br>
    If yes, I don&#39;t think this could be acceptable.<br>
    If the declaration is enough, the copied functions would need at
    least an internal conversion to/from the underlying type, isn&#39;t it?=
<span class=3D"gmail-m_-1377447551499369339gmail-im"><br></span></blockquot=
e><div><br></div><div>My proposal does not need the definition. Yes, I supp=
ose an internal conversion would be needed. The internal conversion would p=
robably work similarly to how inheritance works, even if adding non-static =
members was allowed. As in, the compiler knows that the first piece of the =
class will be the same as the original, and every new member is added at th=
e end.<span class=3D"gmail-m_-1377447551499369339gmail-im"><br></span><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"><span class=3D"gmail-m_-137744=
7551499369339gmail-im"><blockquote type=3D"cite"><div dir=3D"ltr"><div><div=
>B b;<br>
            b.A::bar(5);<br>
            <br>
          </div>
        </div>
      </div>
    </blockquote></span>
    Agreed. And the language let me do that even if you find it could be
    bad practice. I don&#39;t see why your copy approach wouldn&#39;t let m=
e do
    that.<span class=3D"gmail-m_-1377447551499369339gmail-im"><br></span></=
blockquote><div><br></div><div>In my approach the old function is impossibl=
e to hide, so I think that the two cases are different.<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid r=
gb(204,204,204);padding-left:1ex"><span class=3D"gmail-im"><blockquote type=
=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>If in all these cases your answer is &quot;the program wil=
l
              fail to compile, just copy the class by hand&quot; then I thi=
nk
              the feature would be severely limited in what it could
              actually do.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    You are probably right, and the copy should copy every thing and
    give access to everything internally. I need some concrete examples
    to understand what this possibility will solve.<span class=3D"gmail-im"=
><br></span></blockquote><div><br></div><div>Well, for example, a library t=
hat wanted to create strong typedefs of primitive types via wrappers and on=
ly expose certain operations, without getters/setters ;) I&#39;ve added som=
e code later to show you how a possible implementation using this proposal.=
<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor=
der-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> 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
              &quot;wrapper&quot;, which would be the strong typedef. </div=
>
          </div>
        </div>
      </div>
    </blockquote></span>
    I wouldn&#39;t say hiding, just don&#39;t looking inside the underlying
    type. I want to provide access to it (when needed) but only as a
    whole.<span class=3D"gmail-im"><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>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. </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Why it is unusable? The class provide access to everything you want.<sp=
an class=3D"gmail-im"><br></span></blockquote><div><br></div><div>Classes d=
on&#39;t always come with getters and setters for every private field. Espe=
cially if the interface they provide is a high level one. It happens often =
in low-level code that you want to interact with the underlying bits in ver=
y specific ways, but you don&#39;t necessarily want to give that kind of ac=
cess to users. So creating a strong typedef of such a class while adding a =
new mode of operation would be impossible, as the copy won&#39;t have acces=
s to the underlying implementation.<br><br>Another could be when you have t=
o types that you know contain the same (private) data, but should expose di=
fferent public interfaces. Then you could first create the class containing=
 the data, and copy it two times, each time exposing a different interface =
(which would need access to the private data). Once again, I unfortunately =
don&#39;t have a practical use case at the moment. I just think it could be=
 useful.<br><br></div><div>Still the code below is a good use-case I think,=
 since it would be needed to provide strong typedefs of primitive types.<br=
></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"><span class=
=3D"gmail-im"><blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>Applying strong-typing again to a strong-typed class
              would be useless as access to internals would be the same,
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    You can strong-type again. I don&#39;t see the trouble. E.g; you can
    have a energy strong-type and have kinetic_energy, potential_energy
    and=C2=A0 heat_energy strong-type of energy.<br>
    Typing and representation are two different things. Strong types are
    just that. Share a representation and have different types.<span class=
=3D"gmail-im"><br></span></blockquote></div></div></div> <br></div><div>Yes=
, of course. What I mean is, you have created a class which can only create=
 exact copies of it. If you need additional changes, it will probably be ea=
sier to strong-type the original again and create new trampolines from that=
.. This is what I mean by non-extendable.<br><blockquote class=3D"gmail_quot=
e" 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>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&#39;t be used in a
              composable way.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I believe now that strong-type shouldn&#39;t add any new non-static dat=
a
    member</blockquote><div><br></div><div>I start to see what you mean. Bu=
t still, if one could add them, the copy would still &quot;contain&quot; an=
 equivalent of the original class at its beginning. It wouldn&#39;t be guar=
anteed reinterpret_cast-able, but the fields would be there anyway. The ori=
ginal representation is there - so to me it could still be considered a str=
ong-typedef (stretching a bit the definition maybe).<br><br></div><div>Is t=
here any other reason why you don&#39;t like the idea?<br></div><div><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1=
px solid rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-im"><block=
quote type=3D"cite"><div dir=3D"ltr"><div><div><div>A feature that creates =
a
              non-extendable object is like a dead-end.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I must agree with your last sentence, but I don&#39;t think the
    strong-types I&#39;m suggesting are non-extendable?<span class=3D"gmail=
-im"></span> <br></blockquote></div><div><br></div><div>Well, if only the p=
ublic interface is available, than adding new methods to it is pretty much =
equivalent with creating non-member functions (since those work with public=
 interface). Then you might as well remove the ability to add new member fu=
nctions, since non-members will do just fine and there&#39;s no need to hav=
e them as members.<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"=
><span class=3D"gmail-im"><blockquote type=3D"cite"><div dir=3D"ltr"><div><=
div><div>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).<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    We need some probe of concept applied to concrete examples we want
    to solve. I believe a strong type feature must solve the builtin
    type case. If your proposal is not a strong type proposal, then
    forget my comments.<span class=3D"gmail-im"><br></span></blockquote></d=
iv><div><span class=3D"gmail-im"></span><br></div><div>This is how I would =
practically solve the primitive types problem using my proposal:<br><br>---=
---------------------------------------<br><br>// library.hpp<br><br>templa=
te &lt;typename T&gt;<br>class Wrap {<br>=C2=A0=C2=A0=C2=A0 public:<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using base_type =3D T;<br><br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Wrap(const Wrap &amp; other) : t_(o=
ther.t_) {}<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 explicit Wrap(T t=
) : t_(t) {}<br>=C2=A0=C2=A0=C2=A0 <br>=C2=A0=C2=A0=C2=A0 private:<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 T t_;<br>};<br><br>template &lt;typ=
ename C&gt;<br>class ConvertBack : using C {<br>=C2=A0=C2=A0=C2=A0 operator=
 base_type() { return t_; }<br>};<br><br>template &lt;typename C&gt;<br>cla=
ss Plus : using C {<br>=C2=A0=C2=A0=C2=A0 Plus operator+(Plus other) { retu=
rn Plus{t_ + other.t_}; }<br>};<br><br>template &lt;typename C&gt;<br>class=
 Minus : using C {<br>=C2=A0=C2=A0=C2=A0 Minus operator-(Minus other) { ret=
urn Minus{t_ - other.t_}; }<br>};<br><br>template &lt;typename C&gt;<br>cla=
ss Prod : using C {<br>=C2=A0=C2=A0=C2=A0 Prod operator+(Prod other) { retu=
rn Prod{t_ * other.t_}; }<br>};<br><br>template &lt;typename C&gt;<br>class=
 Div : using C {<br>=C2=A0=C2=A0=C2=A0 Div operator/(Div other) { return Di=
v{t_ / other.t_}; }<br>};<br><br>template &lt;typename T&gt;<br>using Arith=
metic =3D Div&lt;Prod&lt;Minus&lt;Plus&lt;Wrap&lt;T&gt;&gt;&gt;&gt;&gt;;<br=
><br>// .... and so on<br><br>// usercode.cpp<br><br>#include &quot;library=
..hpp&quot;<br><br> // Strong typedef of int with +,-,/,*<br>struct MyInt : =
using Arithmetic&lt;int&gt; {}<br><br>// Strong typedef of double with +,- =
convertible to double<br>struct MyDouble : using ConvertBack&lt;Minus&lt;Pl=
us&lt;Wrap&lt;double&gt;&gt;&gt;&gt; {}<br><br>----------------------------=
----------------</div></div></div><div class=3D"gmail_extra"><br></div><div=
 class=3D"gmail_extra">If there&#39;s something missing you&#39;d like to s=
ee how I&#39;d do, let me know. Of course verbosity depends on granularity.=
 If all operations need to be manually selected you&#39;ll have lots of cla=
sses. If the granularity required is less each class could add more operato=
rs at once.<br><br></div><div class=3D"gmail_extra">Note that you need acce=
ss to privates to be able to do this, so this could be an use-case for that=
..<br></div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=
A problem that is not tackled in this code and that we are also discussing =
is what to do with non-member functions (that could possibly take base_type=
 as input). That depends on how non-member functions will be handled in the=
 proposals. If they can be handled I would actually be happier.<br><br><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>
          <div>
            <div>
              <div>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&#39;t think
                this is desirable. I think strong typing should work on
                its own.<br>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    How then you will be able to construct a B from a A if B adds more
    non-static data members?<span class=3D"gmail-im"><br></span></blockquot=
e></div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">One=
 option is to simply define a constructor in B which takes A. Otherwise, it=
 would be the same case when you create a class with a member which the con=
structor does not initialize. Otherwise one exception could be made for con=
structors so that they can be redefined in the new class. This probably mak=
es sense and it shoudn&#39;t be possible to break something (unless one cre=
ates a constructor which does not initialize some fields which are assumed =
initialized by the original class.. but then I believe it&#39;s a reasonabl=
e risk).<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">As you wa=
nt to inherit all the member functions from the underlying
    class, it has a sens to concentrate on member functions. I don&#39;t
    understand why friend functions could not follow the same schema.<span =
class=3D"gmail-im"><br></span></blockquote><div><br></div><div>Well, friend=
 functions are not members, so if you allow copying them, you are allowing =
copying arbitrary non-member functions (which I approve of). The only probl=
em with this is that it is a big change - on top of this proposal. Just tha=
t.<br><span class=3D"gmail-im"><br></span><span class=3D"gmail-im"></span><=
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><div><div>voi=
d foo(int);<br>
                    <br>
                  </div>
                  <div>void foo(double) : using foo(int);<br>
                    <br>
                  </div>
                  <div>to use an analogous syntax to the one in my
                    proposal. Not sure if this is clearer, let me know.<br>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I believe I understand you now but I don&#39;t see how this could help.=
<span class=3D"gmail-im"><br></span></blockquote>=C2=A0</div></div><div cla=
ss=3D"gmail_extra">Well, this would be the way to create the &quot;trampoli=
nes&quot; for non-member functions. When you copy a class, you specify just=
 once from which class you are copying. The compiler can then apply the cha=
nge to all member functions automatically.<br><br>However, you still have t=
o specify non-member functions manually, since the compiler cannot assume y=
ou want them all.<br><span class=3D"gmail-im"><br></span><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><span class=3D"gmail-im"><blockquote type=
=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>and also to A (since C is a type-copy of a
                      type-copy).<br>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    The first Opaque proposal contained a implicit subsumption relation
    that allowed that. I&#39;m all for, but I believe the committee doesn&#=
39;t
    like transitivity in conversions.<span class=3D"gmail-im"><br></span></=
blockquote><br></div><div class=3D"gmail_extra">Well, it is not really tran=
sitivity. As in, the C to A transition does not need an implicit transition=
 from B. The user is explicitly creating the conversion operator. The data =
in C exists, so it can be copied directly. Maybe you mean transitivity in t=
he sense that the compiler needs to remember that C is a copy of B in order=
 for it to know that it is also a copy of A. In that case I agree.<br><br>I=
n any case, I don&#39;t think it is really necessary, it was just an idea.<=
br><br></div><div class=3D"gmail_extra">Best,<br></div><div class=3D"gmail_=
extra">Eugenio Bargiacchi<br></div><div class=3D"gmail_extra"><br></div><di=
v class=3D"gmail_extra"><div class=3D"gmail_quote">On Mon, Jan 2, 2017 at 1=
2:30 AM, Vicente J. Botet Escriba <span dir=3D"ltr">&lt;<a href=3D"mailto:v=
icente.botet@wanadoo.fr" target=3D"_blank">vicente.botet@wanadoo.fr</a>&gt;=
</span> wrote:<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">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF">
    <div class=3D"gmail-m_-1377447551499369339m_-4564586323290602189moz-cit=
e-prefix">Le 01/01/2017 =C3=A0 18:26, Eugenio
      Bargiacchi a =C3=A9crit=C2=A0:<br>
    </div>
    <br>
    Eugenio, I believe the use cases we have both in mind are quite
    different, and so we don&#39;t reach to understand one to each other.<b=
r>
    <br>
    I have a question. Does you copy class proposal needs to have the
    definition of the copied class available?<br>
    If yes, I don&#39;t think this could be acceptable.<br>
    If the declaration is enough, the copied functions would need at
    least an internal conversion to/from the underlying type, isn&#39;t it?=
<span><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">Note that inher=
itance
            allows you to make a member not accessible.<span class=3D"gmail=
-m_-1377447551499369339m_-4564586323290602189gmail-im"></span><br>
            <span class=3D"gmail-m_-1377447551499369339m_-45645863232906021=
89gmail-im"> struct A {</span><br>
            <span class=3D"gmail-m_-1377447551499369339m_-45645863232906021=
89gmail-im"> =C2=A0=C2=A0=C2=A0=C2=A0 int foo(int x) { return x * 2;
              }</span><br>
            <span class=3D"gmail-m_-1377447551499369339m_-45645863232906021=
89gmail-im"> =C2=A0=C2=A0=C2=A0=C2=A0 double bar(double x) { return
              foo(x) * 4.0; }</span><br>
            <span class=3D"gmail-m_-1377447551499369339m_-45645863232906021=
89gmail-im"> };</span><br>
            <span class=3D"gmail-m_-1377447551499369339m_-45645863232906021=
89gmail-im"> </span><br>
            <span class=3D"gmail-m_-1377447551499369339m_-45645863232906021=
89gmail-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 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.<br>
            <br>
            B b;<br>
            b.A::bar(5);<br>
            <br>
          </div>
        </div>
      </div>
    </blockquote></span>
    Agreed. And the language let me do that even if you find it could be
    bad practice. I don&#39;t see why your copy approach wouldn&#39;t let m=
e do
    that.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>There is a difference. In addition, 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>
            <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-m_-1377447551499369339m_-4564586323290602189gmail-im">
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <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">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-m_-1377447551499369339m_-4=
564586323290602189gmail-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 clas=
s=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-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 cl=
ass=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-im"><br>
                <blockquote type=3D"cite">
                  <div dir=3D"ltr">
                    <div>How can you convert in a custom way to the
                      original class?</div>
                  </div>
                </blockquote>
              </span> I don&#39;t see the use case. Maybe you have one.<spa=
n class=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-im"><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 alter
              and access its public interface only. What happens when
              you delete a public method used by a private method? </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Compile error ?<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>What happens when you delete a public attribute used in
              private code?</div>
          </div>
        </div>
      </div>
    </blockquote></span>
    We can not remove data members, otherwise we can not share the same
    representation.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div> What happens to protected code - if not accessible you
              basically make inheritance useless on it? </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Good question. With the wrapping approach, you couldn&#39;t inherit fro=
m
    it. With you approach, the data will be copied. The question is if
    the strong-type has access to this protected data.<br>
    I have never needed to create a duplicate of a class that is part of
    inheritance hierarchy. I&#39;ve always wrapped final classes. Some
    examples will help me to clarify the need.<br>
    I believe we could have duplication having access only to the public
    part and let the derived classes use the protected part.
    Nevertheless I could live providing access to the protected part.<span>=
<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>If in all these cases your answer is &quot;the program wil=
l
              fail to compile, just copy the class by hand&quot; then I thi=
nk
              the feature would be severely limited in what it could
              actually do.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    You are probably right, and the copy should copy every thing and
    give access to everything internally. I need some concrete examples
    to understand what this possibility will solve.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div><br>
            </div>
            <div>I feel that what you are proposing is basically a fast
              way to create PIMPL wrappers.</div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Not at all.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div> 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
              &quot;wrapper&quot;, which would be the strong typedef. </div=
>
          </div>
        </div>
      </div>
    </blockquote></span>
    I wouldn&#39;t say hiding, just don&#39;t looking inside the underlying
    type. I want to provide access to it (when needed) but only as a
    whole.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>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. </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Why it is unusable? The class provide access to everything you want.<sp=
an><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>Applying inheritance to it would require manual
              exposure of all methods, with the limitations we have
              already discussed. </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I don&#39;t follow you here.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>Applying strong-typing again to a strong-typed class
              would be useless as access to internals would be the same,
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    You can strong-type again. I don&#39;t see the trouble. E.g; you can
    have a energy strong-type and have kinetic_energy, potential_energy
    and=C2=A0 heat_energy strong-type of energy.<br>
    Typing and representation are two different things. Strong types are
    just that. Share a representation and have different types.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>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&#39;t be used in a
              composable way.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I believe now that strong-type shouldn&#39;t add any new non-static dat=
a
    member.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div><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 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&#39;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.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I must agree with your last sentence, but I don&#39;t think the
    strong-types I&#39;m suggesting are non-extendable?<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">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"gmail-m_-1377447551499369339m_-4564586323290602189gmail-im"></span><br>
                <span class=3D"gmail-m_-1377447551499369339m_-4564586323290=
602189gmail-im"></span></blockquote>
              <br>
            </div>
            <div>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).<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    We need some probe of concept applied to concrete examples we want
    to solve. I believe a strong type feature must solve the builtin
    type case. If your proposal is not a strong type proposal, then
    forget my comments.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <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"><span class=
=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-im">
                  <blockquote 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 th=
e
                        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 with that approach? <br>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I believe we are not understanding one each other. My two last
    paragraphs don&#39;t concern your proposal. It concerns p0109.<span><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">
                  <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 al=
l
                  new non-static data members. Otherwise I don&#39;t see ho=
w
                  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-m_=
-1377447551499369339m_-4564586323290602189gmail-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>
          </div>
        </div>
      </div>
    </blockquote></span>
    Great.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>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&#39;t think
                this is desirable. I think strong typing should work on
                its own.<br>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    How then you will be able to construct a B from a A if B adds more
    non-static data members?<span><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"><span cla=
ss=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-im">
                    <blockquote type=3D"cite">
                      <div dir=3D"ltr">
                        <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"gmail-m_-137744755149936933=
9m_-4564586323290602189gmail-im"><br>
                  </span></blockquote>
                <div><br>
                </div>
                <div>Mhh, now that you put it this way. I thought about
                  only doing this for classes. </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Do you mean for member functions?<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>While the mechanism 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 dividing them makes no
                  sense. I&#39;d love to hear what you think about this.<br=
>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    As you want to inherit all the member functions from the underlying
    class, it has a sens to concentrate on member functions. I don&#39;t
    understand why friend functions could not follow the same schema.<span>=
<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <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"><span c=
lass=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-im">
                      <blockquote type=3D"cite">
                        <div dir=3D"ltr">
                          <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. <br>
                  </blockquote>
                  <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 more 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&quot; of each other, in some sens=
e. 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 analogous syntax to the one in my
                    proposal. Not sure if this is clearer, let me know.<br>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    I believe I understand you now but I don&#39;t see how this could help.=
<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span=
 class=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-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 de=
fault;<br>
                                </div>
                                <div>};<br>
                                </div>
                                <div>struct C : using B {<br>
                                </div>
                                <div>=C2=A0=C2=A0=C2=A0 operator B() =3D de=
fault;<br>
                                </div>
                                <div>=C2=A0=C2=A0=C2=A0 operator A() =3D de=
fault;<br>
                                  };<br>
                                  <br>
                                </div>
                                <div>Just an idea.<br>
                                </div>
                              </div>
                            </div>
                          </div>
                        </blockquote>
                      </span> I&#39;m lost.<span class=3D"gmail-m_-13774475=
51499369339m_-4564586323290602189gmail-im"><br>
                      </span></blockquote>
                    <div><br>
                    </div>
                    <div>What I mean is, if B is a strong typedef of A,
                      then we can default its conversion operator to A,
                      right? </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Right.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>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), </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Right<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>and also to A (since C is a type-copy of a
                      type-copy).<br>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    The first Opaque proposal contained a implicit subsumption relation
    that allowed that. I&#39;m all for, but I believe the committee doesn&#=
39;t
    like transitivity in conversions.<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"><sp=
an class=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-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"g=
mail-m_-1377447551499369339m_-4564586323290602189gmail-im"><br>
                        </span></blockquote>
                      <div><br>
                      </div>
                      <div>I&#39;m not sure, however to me there&#39;s no
                        difference either way.<br>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    The compiler is always able to do the conversion and the user
    defines when the compiler will do it.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>
                      <div><br>
                        <blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><=
span class=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-im">
                            <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-m=
_-1377447551499369339m_-4564586323290602189gmail-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 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) <span class=3D"gmail-m_-137744755149=
9369339m_-4564586323290602189gmail-im"><br>
                          </span></div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Maybe.<span><br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <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"=
><span class=3D"gmail-m_-1377447551499369339m_-4564586323290602189gmail-im"=
>
                              <blockquote type=3D"cite">
                                <div dir=3D"ltr">
                                  <div>
                                    <div>
                                      <div>
                                        <div>
                                          <div>That&#39;s true, and that&#3=
9;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"=
gmail-m_-1377447551499369339m_-4564586323290602189gmail-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 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&#39;s nothing that the
                            compiler could do to prevent this.<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Well, this is your proposal, and if you don&#39;t want to be able to
    modify the duplicate class, you are then right. But if you where
    able to modify the duplicated class, overriden could have a sense,
    to mean replace it.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>
                      <div>
                        <div>
                          <div><br>
                          </div>
                          <div>Best,<br>
                          </div>
                          <div>Eugenio<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    Vicente<br>
  </div><span>


<p></p>

-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/gkJUVnL-Fmg/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/is<wbr>ocpp.org/d/topic/std-proposals<wbr>/g=
kJUVnL-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.org" target=3D"_blank">std-prop=
osals+unsubscribe@isoc<wbr>pp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9adc5a02-3209-bf63-a684-fb0272da56e0%=
40wanadoo.fr?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/is<wbr>ocpp.org/d/msgid/std-proposals<wbr>/9adc=
5a02-3209-bf63-a684-<wbr>fb0272da56e0%40wanadoo.fr</a>.<br>
</blockquote></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%2BvZEjYakroOWxB8u%2BSCS%3D5u=
DGU5mdYpWpyCbD-qS-P3TQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHfn%3D%=
2BvZEjYakroOWxB8u%2BSCS%3D5uDGU5mdYpWpyCbD-qS-P3TQ%40mail.gmail.com</a>.<br=
 />

--001a113dc5885ce22c05451bbbab--

.
