220 6104 <5224C95D.8040608@wanadoo.fr> article
Path: news.gmane.org!not-for-mail
From: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Proposal: Mixins for C++
Date: Mon, 02 Sep 2013 19:22:37 +0200
Lines: 1047
Approved: news@gmane.org
Message-ID: <5224C95D.8040608@wanadoo.fr>
References: <787081f7-fb40-4507-907d-259318ef2000@isocpp.org> <5221A041.1060001@wanadoo.fr> <15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="------------070207030006060406090300"
X-Trace: ger.gmane.org 1378142563 17182 80.91.229.3 (2 Sep 2013 17:22:43 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Mon, 2 Sep 2013 17:22:43 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDH67CONY4PBBX4SSOIQKGQEX33YAXI@isocpp.org Mon Sep 02 19:22:42 2013
Return-path: <std-proposals+bncBDH67CONY4PBBX4SSOIQKGQEX33YAXI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-bk0-f71.google.com ([209.85.214.71])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDH67CONY4PBBX4SSOIQKGQEX33YAXI@isocpp.org>)
	id 1VGXpo-0000uh-TJ
	for gclcip-std-proposals@m.gmane.org; Mon, 02 Sep 2013 19:22:41 +0200
Original-Received: by mail-bk0-f71.google.com with SMTP id e11sf5217886bkh.2
        for <gclcip-std-proposals@m.gmane.org>; Mon, 02 Sep 2013 10:22:40 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=message-id:date:from:user-agent:mime-version:to:subject:references
         :in-reply-to:x-original-sender:x-original-authentication-results
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe:content-type;
        bh=tZ6b4S0MCcJj8E5pz2aMRM5Ms4uD4QzUiC4OVBP58A0=;
        b=TuD5jxcS0Supdu5s0mUiqd6VudazyZdBpwoqPK1/hMqfMg567dxlfoq0tf8dnJXPe4
         l60cjLj09YvQaSC7OukqRXrH2Z0obPJyOpF3E+qZXzJGdEpDFEoO3PzhML0iUwc8zgk7
         gGhpzFlwAD8mRsLF0+NViae7Zc0rnoiu3r5JvtS5m2ATpDJEzZ4T2vtNg0fQfJ6e4E5v
         An8tF10RQGmK+WEIWb84TsZHpkNxA/ZzCVSjYXVQd2o+Mxe70fJ5qhe8uTMAzFnGUpSh
         YkYXT/eE0j0GY59mk5YPg+/GJjSbiGIsNbZ8NRTYcHt/9WkN1IKT1R4w2UKhzHRXGQWX
         qRUw==
X-Received: by 10.112.234.163 with SMTP id uf3mr6253986lbc.14.1378142560001;
        Mon, 02 Sep 2013 10:22:40 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.152.36.233 with SMTP id t9ls868499laj.49.gmail; Mon, 02 Sep
 2013 10:22:39 -0700 (PDT)
X-Received: by 10.152.8.12 with SMTP id n12mr22551920laa.10.1378142559362;
        Mon, 02 Sep 2013 10:22:39 -0700 (PDT)
Original-Received: from smtp.smtpout.orange.fr (smtp10.smtpout.orange.fr. [80.12.242.132])
        by mx.google.com with ESMTP id m1si6061825lae.130.1969.12.31.16.00.00;
        Mon, 02 Sep 2013 10:22:39 -0700 (PDT)
Received-SPF: neutral (google.com: 80.12.242.132 is neither permitted nor denied by best guess record for domain of vicente.botet@wanadoo.fr) client-ip=80.12.242.132;
Original-Received: from pc3.home ([2.10.128.70])
	by mwinf5d45 with ME
	id LHNd1m00Q1XFuXW03HNdUD; Mon, 02 Sep 2013 19:22:38 +0200
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:17.0) Gecko/20130801 Thunderbird/17.0.8
In-Reply-To: <15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org>
X-Original-Sender: vicente.botet@wanadoo.fr
X-Original-Authentication-Results: mx.google.com;       spf=neutral
 (google.com: 80.12.242.132 is neither permitted nor denied by best guess
 record for domain of vicente.botet@wanadoo.fr) smtp.mail=vicente.botet@wanadoo.fr
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: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:6104
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/6104>

This is a multi-part message in MIME format.
--------------070207030006060406090300
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 02/09/13 16:51, cornedbee@google.com a =E9crit :
>
>
> On Saturday, August 31, 2013 9:50:25 AM UTC+2, Vicente J. Botet=20
> Escriba wrote:
>
>     Hi,
>
>     I agree that we need a way to inject repetitive code into a class.
>     I'm not against not for your proposal. I would like just have more
>     insight on the design rationale and why not try to help you to
>     make a better proposal.
>
>
> Hi Vicente,
>
> Thanks for all the feedback.
>
>     <snip>
>     I have used an alternative approach for mixins. A mixin is a
>     metafunction having a Derived and a Base class. There is a base
>     mixin that defines the self function and that has no Base
>     parameter on the metafunction.
>
>     template <typename Base>
>     struct self_mixin {
>     template <typename Derived>
>       class type : public Base
>        {
>     public:
>         using Base::Base;
>       protected:
>         typedef Derived derived_type;
>         const Derived& self() const { return *static_cast<const
>     Derived*>(this); }
>         Derived& self() { return *static_cast<Derived*>(this); }
>       };
>     };
>
>
>     template <typename T>
>     class smart_ptr_mixin
>     {
>       template <typename Derived, typename Base>
>       class type : public Base {
>     public:
>         using Base::Base;
>       public:
>         T& operator *() const { return *self().get(); }
>
>
> Nit: must be 'return *this->self().get();'
Hrr, you are right. this-> is needed inside the template.
>
>         // etc.
>       };
>     };
>
>     The use of these mixins is done as
>
>     template <typename T>
>     class my_ptr : public mixins<*my_ptr<T>, ****self_mixin**<>*,
>     smart_ptr_mixin<T> >
>     {
>     public:
>       T* get() const { return raw; }
>       // ...
>     };
>
>
>     mixins has as parameter the current class, and the list of mixins
>     starting from the base one.
>
>
> I have actually developed a very similar system at one point, although=20
> it was C++03 and bound to one specific use case (which fixed the=20
> constructors and put a bound on the number of possible mixins,=20
> otherwise it would have been just horrible). It was still incredibly=20
> awkward to use, especially since I needed it in the public interface=20
> of the library I was developing at the time; people writing additional=20
> components within my framework would have had to use it. It was so bad=20
> that I scrapped the design completely.
>
> Nested templates are simply ugly, and that's without trying to define=20
> some of the mixin's methods out-of-line; then you get to multiple=20
> template parameter lists, which I bet 90% of C++ programmers have=20
> never seen in production code, much less written.
Why would you need to define the mixin's methods out-of-line?
>
>     We could make define a MIXIN macro so that
>
>
>     template <typename T>
>     ***MIXIN(*smart_ptr_mixin)
>     {
>     public:
>       T& operator *() const { return **self()*.get(); }
>       // etc.
>     };
>
>     is equivalent to
>
>
>     template <typename T>
>     ***class smart_ptr_mixin **
>     **{**
>     **template <typename Derived, typename Base>
>       class type : public Base {
>     **public:**
>     **    using Base::Base;
>         friend Derived;
>     *  public:
>         T& operator *() const { return **self()*.get(); }
>         // etc.
>       };
>     *};
>     *
>
>
> No, you actually can't. You can't generate the second closing brace=20
> from the macro.
Right. You can try then with

template <typename T>
***MIXIN_BEGIN(*smart_ptr_mixin)
public:
   T& operator *() const { return **self()*.get(); }
   // etc.
***MIXIN_END*;

I agree that don't having the braces is ugly.

Alternatively you can do

template <typename T>
class smart_ptr_mixin
{
*MIXIN_BEGIN;*
public:
   T& operator *() const { return **self()*.get(); }
   // etc.
*MIXIN_END;*
};

that could expand to

template <typename T>
**class smart_ptr_mixin
{
***template <typename Derived, typename Base>
   class type : public Base {
**public:**
**    using Base::Base;
**typedef Derived derived_type;
const Derived& self() const { return *static_cast<const Derived*>(this); }
Derived& self() { return *static_cast<Derived*>(this); }
* public:
     T& operator *() const { return **self()*.get(); }
     // etc.
*}*;
*};
*

So that you can use self() directly.
> You could define the macro to expand to something like
>
> class NAME {
>   template <typename Derived, typename Base> class type;
> };
> template <typename Derived, typename Base> class NAME::type /* user=20
> continues here */
>
> but that breaks for mixin templates, which require you to give the=20
> template parameter list and argument list forms to the macro, and then=20
> you run into the usual problems with commas in angle brackets in macro=20
> arguments, and even if you manage to solve it, it's one gigantic mess.
>
>     *
>     *This approach solve some of the drawbacks you mention, while not
>     all.
>
>
> I don't really thinks it solves any of the drawbacks. The boilerplate=20
> may be somewhat reduced, if you manage to write the macro, but all the=20
> other points in my list remain unaffected.
I'm not proposing these macros. I'm just seen how close a mixin=20
implementation (compiler) to a CRTP model it could be. The advantage is=20
that the model is well known, and so the new feature will be only=20
syntactic sugar, which clearly is needed.
>
>     Does making mixins act like data member makes then increase the
>     size of the class?
>     Have you considered to see them as part of the inheritance hierarchy?
>
>
> Mixins don't act like data members for any purpose but=20
> construction/destruction.
OK.
>
>
>     class foo : public mixin X
>     {
>     };
>
>
> This runs into the problems I mentioned about the completeness of foo=20
> within the mixin.
I don't see this as a problem, but a future of mixins. A mixin has only=20
sense once instantiated.
>
>>     Since the mixin is a template, the type of its 'this' pointer is
>>     dependent.
>>     The syntax for acessing members is the same as that for access to
>>     members of
>>     dependent base classes: use 'this->' to make the expression
>>     dependent and delay
>>     lookup until instantiation time.
>     Have you considered adding a self keyword instead of using this?
>
>
> For a moment, but I don't see the point. 'self' is completely=20
> impossible to add, since it is widely used as a variable/function=20
> name, and the new use would be in a context where a variable name can=20
> appear. If you know any other conveniently short and logical words=20
> that aren't already in wide use in expression context, I'd love to=20
> hear about them, though.
The keyword can be contextual.
>
>>
>>     Mixins can contain every kind of declaration that classes can,
>>     including inner
>>     types, data members, and more mixin directives. Mixins cannot
>>     have base classes.
>>     (POD: Should they be able to? The bases could be appended to the
>>     list of bases
>>     of the embedding class. What kind of problems could that cause?)
>
>     I don't see why the introduction of the last constraint is needed.
>     With the CRTP model there is no such limitation
>
>
> The constraint isn't *needed*, it's just something that I didn't want=20
> to think about too hard. I would have to decide on the order of=20
> initialization, and from a compiler writer viewpoint, I'm not sure=20
> what it would mean to change the inheritance graph of a class in the=20
> middle of the body.
Ok.
>
>>     - Functions overload. If they cannot overload, it's an error.
>     The CRTP pattern allow to manage with this case as each mixin can
>     relay on the base mixin. I see this is an advantage of the
>     inheritance approach respect to the member approach.
>
>     For example, several mixins could define a trace function that use
>     the base one and add something else
>
>     void trace() {
>       this->base_type.trace();
>       // ....
>     }
>
>
> This is a good point. Relaying calls from one mixin to another is a=20
> use case I haven't considered so far. I have no good solution for this=20
> at the moment.
The alternative CRTP model would allow it without any trouble.
>
>>     In addition, it might be useful to make it possible for mixins to
>>     have sections
>>     that are not made visible to the embedding class (e.g. a "mixin:"
>>     access
>>     specifier), although I am hesitant to really do this, because I
>>     can see a
>>     pattern developing where the entire class body is always put in a
>>     mixin, and a
>>     mixin: specifier is used to create "truly hidden" private sections.
>     Why using private as for class is not enough? What am I missing?
>
>
> In the base class model, conflicting names just hide each other; they=20
> are not by themselves an error. But going with the model of inheriting=20
> conflicting names from multiple bases might be the best model for what=20
> I want to achieve after all.
Sorry, I don't understand. Are you telling inheriting from multiple bases?

Best,
Vicente

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--------------070207030006060406090300
Content-Type: text/html; charset=ISO-8859-1

<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Le 02/09/13 16:51, <a class="moz-txt-link-abbreviated" href="mailto:cornedbee@google.com">cornedbee@google.com</a>
      a &eacute;crit&nbsp;:<br>
    </div>
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr"><br>
        <br>
        On Saturday, August 31, 2013 9:50:25 AM UTC+2, Vicente J. Botet
        Escriba wrote:
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000"> Hi,<br>
            <br>
            I agree that we need a way to inject repetitive code into a
            class. I'm not against not for your proposal. I would like
            just have more insight on the design rationale and why not
            try to help you to make a better proposal.<br>
            <br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>Hi Vicente,</div>
        <div><br>
        </div>
        <div>Thanks for all the feedback.</div>
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000"> &lt;snip&gt;<br>
            I have used an alternative approach for mixins. A mixin is a
            metafunction having a Derived and a Base class. There is a
            base mixin that defines the self function and that has no
            Base parameter on the metafunction.<br>
            <br>
            <span style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace">template

                          &lt;typename Base&gt;<br>
                        </span></span></span></span><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"></span></span></span></span></span></span></span></span>struct

              self_mixin {<br>
              &nbsp;&nbsp; </span><span style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace">template
                &lt;typename Derived&gt;<br>
              </span>&nbsp; class type </span><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace">: public Base
              </span><br>
              &nbsp;&nbsp; {<br>
              &nbsp;&nbsp; </span><span style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace">public:<br>
                &nbsp;&nbsp;&nbsp; using Base::Base;<br>
              </span>&nbsp; protected:<br>
              &nbsp;&nbsp;&nbsp; typedef Derived derived_type;<br>
            </span><span style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace">&nbsp;&nbsp;&nbsp; const
                Derived&amp; self() const { return *static_cast&lt;const
                Derived*&gt;(this); }<br>
              </span></span><span style="font-family:courier
              new,monospace"><span style="font-family:courier
                new,monospace"><span style="font-family:courier
                  new,monospace">&nbsp;&nbsp;&nbsp; Derived&amp; self() { return
                  *static_cast&lt;Derived*&gt;(this); }<br>
                </span></span>&nbsp; };<br>
              };<br>
            </span><br>
            <br>
            <span style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace">template

                        &lt;typename T&gt;<br>
                      </span></span></span></span><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"></span></span></span></span></span></span>class

                smart_ptr_mixin&nbsp; <br>
                {<br>
              </span></span><span style="font-family:courier
              new,monospace"><span style="font-family:courier
                new,monospace"><span style="font-family:courier
                  new,monospace"><span style="font-family:courier
                    new,monospace"><span style="font-family:courier
                      new,monospace"><span style="font-family:courier
                        new,monospace">&nbsp; template &lt;typename Derived,
                        typename Base&gt;<br>
                      </span></span>&nbsp; class type : public Base {<br>
                  </span></span><span style="font-family:courier
                  new,monospace"><span style="font-family:courier
                    new,monospace"><span style="font-family:courier
                      new,monospace"><span style="font-family:courier
                        new,monospace"></span></span></span></span></span></span><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace">&nbsp;
                      public:<br>
                      &nbsp;&nbsp;&nbsp; using Base::Base;<br>
                    </span></span></span>&nbsp; public:<br>
                &nbsp;&nbsp;&nbsp; T&amp; operator *() const { return *self().get(); }<br>
              </span></span></div>
        </blockquote>
        <div><br>
        </div>
        <div>Nit: must be 'return *this-&gt;self().get();'</div>
      </div>
    </blockquote>
    Hrr, you are right. this-&gt; is needed inside the template.<br>
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"> &nbsp;&nbsp;&nbsp; // etc.<br>
              </span></span><span style="font-family:courier
              new,monospace"><span style="font-family:courier
                new,monospace">&nbsp; };<br>
                };</span></span><br>
            <br>
            The use of these mixins is done as<br>
            <br>
            <span style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace">template
                &lt;typename T&gt;<br>
                class my_ptr : public mixins&lt;</span></span><b><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace">my_ptr&lt;T&gt;,&nbsp;</span></span></b><b><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"></span></span></b><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><b><span
                    style="font-family:courier new,monospace">self_mixin</span></b><b>&lt;&gt;</b><wbr>,
              </span></span><span style="font-family:courier
              new,monospace"><span style="font-family:courier
                new,monospace"><span style="font-family:courier
                  new,monospace"><span style="font-family:courier
                    new,monospace"></span></span><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace">smart_ptr_mixin&lt;</span></span>T&gt;</span></span>
                &gt; <br>
                {<br>
              </span></span><span style="font-family:courier
              new,monospace"><span style="font-family:courier
                new,monospace">public:<br>
              </span></span><span style="font-family:courier
              new,monospace"><span style="font-family:courier
                new,monospace">&nbsp; T* get() const { return raw; }<br>
                &nbsp; // ...<br>
                };</span></span><br>
            <br>
            <br>
            <span style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace">mixins has as
                parameter the current class, and the list of mixins
                starting from the base one.<br>
              </span></span></div>
        </blockquote>
        <div><br>
        </div>
        <div>I have actually developed a very similar system at one
          point, although it was C++03 and bound to one specific use
          case (which fixed the constructors and put a bound on the
          number of possible mixins, otherwise it would have been just
          horrible). It was still incredibly awkward to use, especially
          since I needed it in the public interface of the library I was
          developing at the time; people writing additional components
          within my framework would have had to use it. It was so bad
          that I scrapped the design completely.</div>
        <div><br>
        </div>
        <div>Nested templates are simply ugly, and that's without trying
          to define some of the mixin's methods out-of-line; then you
          get to multiple template parameter lists, which I bet 90% of
          C++ programmers have never seen in production code, much less
          written.</div>
      </div>
    </blockquote>
    Why would you need to define the mixin's methods out-of-line?
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>&nbsp;<br>
        </div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace">We could make
                define a MIXIN macro so that<br>
                <br>
              </span></span><br>
            <span style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace">template

                            &lt;typename T&gt;<br>
                          </span></span></span></span><b><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"><span
                                style="font-family:courier
                                new,monospace"><span
                                  style="font-family:courier
                                  new,monospace"></span></span></span></span></span></span></b><b>MIXIN(</b>smart_ptr_mixin)&nbsp;

                    <br>
                    {<br>
                  </span></span><span style="font-family:courier
                  new,monospace"><span style="font-family:courier
                    new,monospace">public:<br>
                    &nbsp; T&amp; operator *() const { return *<b>self()</b>.get();
                    }<br>
                    &nbsp; // etc.<br>
                  </span></span><span style="font-family:courier
                  new,monospace"><span style="font-family:courier
                    new,monospace">};<br>
                    <br>
                    is equivalent to<br>
                    <br>
                  </span></span><br>
                <span style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"><span
                                style="font-family:courier
                                new,monospace">template &lt;typename
                                T&gt;<br>
                              </span></span></span></span><b><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"><span
                                style="font-family:courier
                                new,monospace"><span
                                  style="font-family:courier
                                  new,monospace"><span
                                    style="font-family:courier
                                    new,monospace"><span
                                      style="font-family:courier
                                      new,monospace"></span></span></span></span></span></span></b><b>class

                          smart_ptr_mixin&nbsp; </b><b><br>
                        </b><b> {</b><b><br>
                          &nbsp; </b></span></span><b><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"><span
                                style="font-family:courier
                                new,monospace"><span
                                  style="font-family:courier
                                  new,monospace">template &lt;typename
                                  Derived, typename Base&gt;<br>
                                </span></span>&nbsp; class type : public Base
                              {<br>
                            </span></span><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"><span
                                style="font-family:courier
                                new,monospace"><span
                                  style="font-family:courier
                                  new,monospace"></span></span></span></span></span></span></b><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"><b>&nbsp;
                                public:</b><b><br>
                              </b><b>&nbsp;&nbsp;&nbsp; using Base::Base;<br>
                                &nbsp;&nbsp;&nbsp; friend Derived;<br>
                              </b></span></span></span>&nbsp; public:<br>
                        &nbsp;&nbsp;&nbsp; T&amp; operator *() const { return *<b>self()</b>.get();

                        }<br>
                        &nbsp;&nbsp;&nbsp; // etc.<br>
                      </span></span><span style="font-family:courier
                      new,monospace"><span style="font-family:courier
                        new,monospace">&nbsp; };<br>
                        <b>};<br>
                        </b></span></span></span></span></span></span></div>
        </blockquote>
        <div><br>
        </div>
        <div>No, you actually can't. You can't generate the second
          closing brace from the macro. </div>
      </div>
    </blockquote>
    Right. You can try then with<br>
    <br>
    <span style="font-family:courier new,monospace"><span
        style="font-family:courier new,monospace"><span
          style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace">template
                    &lt;typename T&gt;<br>
                  </span></span></span></span><b><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"></span></span></span></span></span></span></b><b>MIXIN_BEGIN(</b>smart_ptr_mixin)&nbsp;

            <br>
          </span></span><span style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace">public:<br>
            &nbsp; T&amp; operator *() const { return *<b>self()</b>.get(); }<br>
            &nbsp; // etc.<br>
          </span></span><span style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace"></span></span></span></span><span
      style="font-family:courier new,monospace"><span
        style="font-family:courier new,monospace"><span
          style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"></span></span></span></span><b><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"><span
                                style="font-family:courier
                                new,monospace"><span
                                  style="font-family:courier
                                  new,monospace"></span></span></span></span></span></span></b><b>MIXIN_END</b></span></span></span></span>;<br>
            <br>
            I agree that don't having the braces is ugly.<br>
            <br>
            Alternatively you can do<br>
          </span></span></span></span><br>
    <span style="font-family:courier new,monospace"><span
        style="font-family:courier new,monospace"><span
          style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace">template
                    &lt;typename T&gt;<br>
                    class </span></span></span></span>smart_ptr_mixin<br>
            {<br>
            &nbsp; <b>MIXIN_BEGIN;</b><br>
            &nbsp; </span></span><span style="font-family:courier
          new,monospace"><span style="font-family:courier new,monospace">public:<br>
            &nbsp; T&amp; operator *() const { return *<b>self()</b>.get(); }<br>
            &nbsp; // etc.<br>
          </span></span></span></span><span style="font-family:courier
      new,monospace"><span style="font-family:courier new,monospace"><span
          style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace">&nbsp; <b>MIXIN_END;</b><br>
                  </span></span></span></span>}</span></span></span></span><span
      style="font-family:courier new,monospace"><span
        style="font-family:courier new,monospace"><span
          style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace">;<br>
            <br>
            that could expand to<br>
          </span></span></span></span><br>
    <span style="font-family:courier new,monospace"><span
        style="font-family:courier new,monospace"> <span
          style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace">template

                        &lt;typename T&gt;<br>
                      </span></span></span></span><b><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace"><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace"></span></span></span></span></span></span></b>class

                smart_ptr_mixin&nbsp; <br>
                {<br>
                <b>&nbsp; </b></span></span><b><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><span
                          style="font-family:courier new,monospace">template

                          &lt;typename Derived, typename Base&gt;<br>
                        </span></span>&nbsp; class type : public Base {<br>
                    </span></span><span style="font-family:courier
                    new,monospace"><span style="font-family:courier
                      new,monospace"><span style="font-family:courier
                        new,monospace"><span style="font-family:courier
                          new,monospace"></span></span></span></span></span></span></b><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><b>&nbsp;
                        public:</b><b><br>
                      </b><b>&nbsp;&nbsp;&nbsp; using Base::Base;<br>
                      </b></span></span></span></span></span></span></span></span></span><span
      style="font-family:courier new,monospace"><span
        style="font-family:courier new,monospace"><span
          style="font-family:courier new,monospace"><span
            style="font-family:courier new,monospace"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><b><span
                          style="font-family:courier new,monospace">&nbsp;&nbsp;&nbsp;
                          typedef Derived derived_type;<br>
                        </span><span style="font-family:courier
                          new,monospace"><span
                            style="font-family:courier new,monospace">&nbsp;&nbsp;&nbsp;
                            const Derived&amp; self() const { return
                            *static_cast&lt;const Derived*&gt;(this); }<br>
                          </span></span><span style="font-family:courier
                          new,monospace"><span
                            style="font-family:courier new,monospace"><span
                              style="font-family:courier new,monospace">&nbsp;&nbsp;&nbsp;
                              Derived&amp; self() { return
                              *static_cast&lt;Derived*&gt;(this); }<br>
                            </span></span></span></b></span></span></span>&nbsp;
                public:<br>
                &nbsp;&nbsp;&nbsp; T&amp; operator *() const { return *<b>self()</b>.get();

                }<br>
                &nbsp;&nbsp;&nbsp; // etc.<br>
              </span></span><span style="font-family:courier
              new,monospace"><span style="font-family:courier
                new,monospace">&nbsp; <b>}</b>;<br>
                <b>};<br>
                </b></span></span></span></span></span></span>
    <div><br>
      So that you can use self() directly.<br>
    </div>
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>You could define the macro to expand to something like</div>
        <div><br>
        </div>
        <div>class NAME {</div>
        <div>&nbsp; template &lt;typename Derived, typename Base&gt; class
          type;</div>
        <div>};</div>
        <div>template &lt;typename Derived, typename Base&gt; class
          NAME::type /* user continues here */</div>
        <div><br>
        </div>
        <div>but that breaks for mixin templates, which require you to
          give the template parameter list and argument list forms to
          the macro, and then you run into the usual problems with
          commas in angle brackets in macro arguments, and even if you
          manage to solve it, it's one gigantic mess.</div>
        <div><br>
        </div>
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000"><span
              style="font-family:courier new,monospace"><span
                style="font-family:courier new,monospace"><span
                  style="font-family:courier new,monospace"><span
                    style="font-family:courier new,monospace"><span
                      style="font-family:courier new,monospace"><span
                        style="font-family:courier new,monospace"><b> <br>
                        </b>This approach solve some of the drawbacks
                        you mention, while not all. <br>
                      </span></span></span></span></span></span></div>
        </blockquote>
        <div><br>
        </div>
        <div>I don't really thinks it solves any of the drawbacks. The
          boilerplate may be somewhat reduced, if you manage to write
          the macro, but all the other points in my list remain
          unaffected.</div>
      </div>
    </blockquote>
    I'm not proposing these macros. I'm just seen how close a mixin
    implementation (compiler) to a CRTP model it could be. The advantage
    is that the model is well known, and so the new feature will be only
    syntactic sugar, which clearly is needed.
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000"> Does making mixins act
            like data member makes then increase the size of the class?<br>
            Have you considered to see them as part of the inheritance
            hierarchy?<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>Mixins don't act like data members for any purpose but
          construction/destruction.</div>
      </div>
    </blockquote>
    OK.<br>
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000"> <br>
            <span style="font-family:courier new,monospace">class foo :
              public mixin X <br>
              {<br>
              };</span></div>
        </blockquote>
        <div><br>
        </div>
        <div>This runs into the problems I mentioned about the
          completeness of foo within the mixin.</div>
      </div>
    </blockquote>
    I don't see this as a problem, but a future of mixins. A mixin has
    only sense once instantiated.<br>
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000">
            <blockquote type="cite">
              <div dir="ltr"> Since the mixin is a template, the type of
                its 'this' pointer is dependent.<br>
                The syntax for acessing members is the same as that for
                access to members of<br>
                dependent base classes: use 'this-&gt;' to make the
                expression dependent and delay<br>
                lookup until instantiation time.<br>
              </div>
            </blockquote>
            Have you considered adding a self keyword instead of using
            this?<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>For a moment, but I don't see the point. 'self' is
          completely impossible to add, since it is widely used as a
          variable/function name, and the new use would be in a context
          where a variable name can appear. If you know any other
          conveniently short and logical words that aren't already in
          wide use in expression context, I'd love to hear about them,
          though.</div>
      </div>
    </blockquote>
    The keyword can be contextual.<br>
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000">
            <blockquote type="cite">
              <div dir="ltr"><br>
                Mixins can contain every kind of declaration that
                classes can, including inner<br>
                types, data members, and more mixin directives. Mixins
                cannot have base classes.<br>
                (POD: Should they be able to? The bases could be
                appended to the list of bases<br>
                of the embedding class. What kind of problems could that
                cause?)<br>
              </div>
            </blockquote>
            <br>
            I don't see why the introduction of the last constraint is
            needed. With the CRTP model there is no such limitation<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>The constraint isn't *needed*, it's just something that I
          didn't want to think about too hard. I would have to decide on
          the order of initialization, and from a compiler writer
          viewpoint, I'm not sure what it would mean to change the
          inheritance graph of a class in the middle of the body.</div>
      </div>
    </blockquote>
    Ok.<br>
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000">
            <blockquote type="cite">
              <div dir="ltr">- Functions overload. If they cannot
                overload, it's an error.<br>
              </div>
            </blockquote>
            The CRTP pattern allow to manage with this case as each
            mixin can relay on the base mixin. I see this is an
            advantage of the inheritance approach respect to the member
            approach.<br>
            <br>
            For example, several mixins could define a trace function
            that use the base one and add something else<br>
            <br>
            void trace() {<br>
            &nbsp; this-&gt;base_type.trace();<br>
            &nbsp; // ....<br>
            }<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>This is a good point. Relaying calls from one mixin to
          another is a use case I haven't considered so far. I have no
          good solution for this at the moment.</div>
      </div>
    </blockquote>
    The alternative CRTP model would allow it without any trouble.<br>
    <blockquote
      cite="mid:15667a97-e6f3-46fb-b346-6f248b5815cf@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div>&nbsp;</div>
        <blockquote class="gmail_quote" style="margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div bgcolor="#FFFFFF" text="#000000">
            <blockquote type="cite">
              <div dir="ltr">In addition, it might be useful to make it
                possible for mixins to have sections<br>
                that are not made visible to the embedding class (e.g. a
                "mixin:" access<br>
                specifier), although I am hesitant to really do this,
                because I can see a<br>
                pattern developing where the entire class body is always
                put in a mixin, and a<br>
                mixin: specifier is used to create "truly hidden"
                private sections.<br>
              </div>
            </blockquote>
            Why using private as for class is not enough? What am I
            missing?<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>In the base class model, conflicting names just hide each
          other; they are not by themselves an error. But going with the
          model of inheriting conflicting names from multiple bases
          might be the best model for what I want to achieve after all.
          <br>
        </div>
      </div>
    </blockquote>
    Sorry, I don't understand. Are you telling inheriting from multiple
    bases?<br>
    <br>
    Best,<br>
    Vicente<br>
  </body>
</html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

--------------070207030006060406090300--

.
