<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Template Parameter ist ein Template]]></title><description><![CDATA[<p>Hi,</p>
<p>folgender Code erzeugt im MSVC7.1 jede Menge Syntaxfehler, was ich auch irgendwie nachvollziehen kann.</p>
<pre><code class="language-cpp">template &lt;typename T, typename Base&gt;
T&amp; down(Base&lt;T&gt;&amp; b)
{
    return *static_cast&lt;T*&gt;(&amp;b);
}
</code></pre>
<p>Meine Frage ist: Wie kann ich das trotzdem schreiben? Es geht mir speziell darum, dass der Parameter 'Base' eben ein Template eines Templates ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/185334/template-parameter-ist-ein-template</link><generator>RSS for Node</generator><lastBuildDate>Thu, 24 Sep 2026 03:27:02 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/185334.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 24 Jun 2007 11:06:45 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 11:06:45 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>folgender Code erzeugt im MSVC7.1 jede Menge Syntaxfehler, was ich auch irgendwie nachvollziehen kann.</p>
<pre><code class="language-cpp">template &lt;typename T, typename Base&gt;
T&amp; down(Base&lt;T&gt;&amp; b)
{
    return *static_cast&lt;T*&gt;(&amp;b);
}
</code></pre>
<p>Meine Frage ist: Wie kann ich das trotzdem schreiben? Es geht mir speziell darum, dass der Parameter 'Base' eben ein Template eines Templates ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1312661</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312661</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Sun, 24 Jun 2007 11:06:45 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 11:11:01 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template &lt;typename T, template&lt; typename T &gt; class Base&gt;
</code></pre>
<p>So?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1312665</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312665</guid><dc:creator><![CDATA[David_pb]]></dc:creator><pubDate>Sun, 24 Jun 2007 11:11:01 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 11:17:21 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template&lt; typename T, template&lt; typename &gt; class Base &gt; 
T&amp; down( Base&lt; T &gt;&amp; b) 
{ 
    return *static_cast&lt;T*&gt;(&amp;b); 
}
</code></pre>
<p>Sowas?</p>
<p>EDIT: too late <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Nochmal EDIT: Wichtig ist hier &quot;class Base&quot; in der Templateparameterliste. &quot;typename Base&quot; greift hier nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1312668</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312668</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Sun, 24 Jun 2007 11:17:21 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 11:26:33 GMT]]></title><description><![CDATA[<p>Perverses Zeug. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
<p>Vielen Dank.</p>
<p>Damit habe ich es endlich geschafft, den <a href="http://en.wikipedia.org/wiki/Barton-Nackman_trick" rel="nofollow">Barton-Nackman-Trick</a> ohne virtuelle Funktionen rekursiv zu implementieren, wie in Haskell.</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
struct equitable {
    typedef equitable&lt;T&gt; self_t;

    friend bool operator ==(self_t const&amp; a, self_t const&amp; b)
    {
        return not (down(a) != down(b));
    }

    friend bool operator !=(self_t const&amp; a, self_t const&amp; b)
    {
        return not (down(a) == down(b));
    }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1312671</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312671</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Sun, 24 Jun 2007 11:26:33 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 14:23:04 GMT]]></title><description><![CDATA[<p>ein wenig lesbarer wäre es so:</p>
<pre><code class="language-cpp">template &lt;typename T, typename Base&gt;
T&amp; down(Base&lt;T&gt;&amp; b)
{
    return static_cast&lt;T&amp;&gt;(b);
}
</code></pre>
<p>und noch besser wirds so:</p>
<pre><code class="language-cpp">template&lt;class Derived&gt;
class TypeSave
{
    protected:
        Derived&amp; down()
        {
             return static_cast&lt;Derived&amp;&gt;(*this);
        }
};
template &lt;typename T&gt;
struct equitable : TypeSave&lt;T&gt;
{
    typedef equitable&lt;T&gt; self_t;

    friend bool operator ==(self_t const&amp; a, self_t const&amp; b)
    {
        return not (a.down() != b.down());
    }
};
</code></pre>
<p>so verhinderst du noch, dass down auf Typen angewendet wird, die nicht von ihrem template parameter geerbt haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1312744</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312744</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sun, 24 Jun 2007 14:23:04 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 15:12:24 GMT]]></title><description><![CDATA[<p>Hi Otze,</p>
<p>hmm. Irgendwie muss ich da wohl einer geistigen Umnachtung verfallen sein. Keine Ahnung, was der Zeiger-Cast-Wahn in meinem Code soll.</p>
<p>Die 'TypeSafe'-Basisklasse ist auch eine gute Idee, das hatte ich in meinem Code aber deswegen nicht gemacht, weil ich eine spezielle Objekthierarchie nachahmen wollte (nämlich eine ähnlich zu der in Haskell). Wenn ich hier mit dieser Basisklasse arbeite, bekomme ich den Fehler &quot;ambiguous conversions&quot;. Ich vermute mal, dass es daran liegt, dass hier diamond-shaped-inheritance zum Vorschein kommt. Ich habe nämlich nicht nur die Basisklasse 'equitable' sondern z.B. auch 'writable', welche dann ebenfalls von 'TypeSafe' abgeleitet wäre und außerdem eine Implementierung 'integer', welche sowohl von 'equitable' als auch von 'writable' erbt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1312784</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312784</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Sun, 24 Jun 2007 15:12:24 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 18:05:08 GMT]]></title><description><![CDATA[<p>ich weis jetzt nicht, ob ne virtuelle vererbung in dieser konstellation irgendwelche nachteile haben würde. immerhin ist das objekt leer, hat keine virtuellen methoden und könnte zur compilezeit theoretisch komplett rausoptimiert werden. Ansonsten würde dies das von dir genannte problem beheben.</p>
<p>die alternative wäre sonst sowas häßliches:</p>
<pre><code class="language-cpp">template&lt;class Derived,int id&gt;
class TypeSave
{
    protected:
        Derived&amp; down()
        {
             return static_cast&lt;Derived&amp;&gt;(*this);
        }
};
template &lt;typename T&gt;
struct equitable : TypeSave&lt;T, 1&gt;//andere kriegen dann andere nummern
{
    typedef equitable&lt;T&gt; self_t;

    friend bool operator ==(self_t const&amp; a, self_t const&amp; b)
    {
        return not (a.down() != b.down());
    }
};
</code></pre>
<p>um die nummernvergabe dann eindeutig zu machen, könnte man als nächsten schritt ne typliste bauen, die dann mit template magie das ganze zusammenbastelt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
<p>und wenn du die Objekthierarchie so nachahmen willst, kannste vielleicht protected vererbung nutzen, ich denk die wär hier vielleicht nützlich. dann wird ein cast nach TypeSave unterbunden. Obwohl sich dann virtual nicht mehr anbietet. also entweder typlisten und protected oder virtual und ne nicht perfekte typhirarchie.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1312923</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312923</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sun, 24 Jun 2007 18:05:08 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 18:11:36 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>ich weis jetzt nicht, ob ne virtuelle vererbung in dieser konstellation irgendwelche nachteile haben würde. [...] Ansonsten würde dies das von dir genannte problem beheben.</p>
</blockquote>
<p>Klar, war auch mein erster Gedanke, ist aber nicht so. Oder ich mache halt etwas falsch; jedenfalls erhalte ich jetzt den Fehler.</p>
<p>&quot;Kann 'TypeSafe&lt;T&gt;<em>' nicht nach 'integer</em>' konvertieren. Konversion ausgehend von einer impliziten virtuellen Basisklasse&quot;.</p>
<p>Ich habe mal versucht, den Code anzuändern, um explizit eine der Basisklassen zu verwenden, aber auch das klappt nicht, selber Fehler (ich habe einfach *alle* Basisklassen virtuell gemacht):</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
struct equitable : virtual TypeSafe&lt;T&gt; {
    typedef equitable&lt;T&gt; self_t;

    inline friend bool operator !=(self_t const&amp; a, self_t const&amp; b)
    {
        return not (a.self_t::down() == b.self_t::down());
    }
};
</code></pre>
<p>Eigentlich wundert es mich auch nicht weiter, dass das nicht klappt. Nur: *wie* klappt es dann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1312934</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312934</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Sun, 24 Jun 2007 18:11:36 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 19:08:49 GMT]]></title><description><![CDATA[<p>scheinbar klappt der static_cast trick nicht mit virtuellen basisklassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1312969</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1312969</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sun, 24 Jun 2007 19:08:49 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 20:40:19 GMT]]></title><description><![CDATA[<p>Interessante Idee mit dem static_cast Trick,<br />
aber fehlt an dieser Stelle nicht einfach nen virtual?</p>
<pre><code class="language-cpp">Derived&amp; down()
        {
             return static_cast&lt;Derived&amp;&gt;(*this);
        }
</code></pre>
<p>Ansonsten wird bei einem Object, das von einem Derived-Object abgeleitet wird<br />
und selbst wieder Derived besitzt doch die Methode des Basis-Objektes<br />
verwendet, falls man einen Basis-Zeiger hat und folglich wird der falsche<br />
cast benutzt. Ein virtual müßte doch (ungetestet) Abhilfe schaffen...</p>
<p>btw:<br />
Irgendwie komm ich mir komisch vor, wenn ich mich mit meinen paar Beiträgen<br />
in die Diskussion zwischen zwei alteingesessenen einbringe.<br />
Also, wenn ich Mist schreibe: SORRY</p>
<p>Gruß,<br />
CSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313001</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313001</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Sun, 24 Jun 2007 20:40:19 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 21:03:27 GMT]]></title><description><![CDATA[<p>Hab es mir nochmal überlegt ^^, das geht wegen der Referenz im<br />
Rückgabetyp wohl nicht, aber wenn man da nen void* Zeiger zurückliefert?<br />
Ansonsten erwarteter ja nichts höheres, denn der Rückgabetyp der<br />
Basis-Klasse wird ja nicht angepaßt.</p>
<p>EDIT: *argh* dann funct der selbstgeschriebene == Operator ja nicht, sondern<br />
nur nen Zeiger vergleich.<br />
Also vergeßt es einfach <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Gruß,<br />
CSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313006</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313006</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Sun, 24 Jun 2007 21:03:27 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 21:59:10 GMT]]></title><description><![CDATA[<p>CSpille schrieb:</p>
<blockquote>
<p>btw:<br />
Irgendwie komm ich mir komisch vor, wenn ich mich mit meinen paar Beiträgen<br />
in die Diskussion zwischen zwei alteingesessenen einbringe.<br />
Also, wenn ich Mist schreibe: SORRY</p>
</blockquote>
<p>He, schäm dich niemals, wenn du versuchst deine gedanken für eine problemlösung beizusteuern. Selbst wenn es nicht stimmen sollte, ist das immernoch bei weitem besser, als einen guten gedanken zu verwerfen!</p>
<p>So, mal eine Lösung die ich mir mal so überlegt hab:</p>
<pre><code class="language-cpp">//da der virtual ansatz nicht klappt, muss der Save dann wohl so aussehen:
template&lt;class Derived,int i&gt;
class TypeSave
{
    protected:
        Derived&amp; down()
        {
             return static_cast&lt;Derived&amp;&gt;(*this);
        }
        const Derived&amp; down()const
        {
             return static_cast&lt;const Derived&amp;&gt;(*this);
        }
};
//was nicht geht, ist dann sowas machen:
template &lt;typename T&gt;
struct equitable :public TypeSave&lt;T,1&gt;
{
};
//das ist schlecht erweiterbar, weil alle wissen müssten, welche Zahlen bereits belegt sind.

//Also schlag ich mal die Holzhammer Methode vor
struct equitable
{
    public:
        template&lt;typename T,int i&gt;
        struct Operators:public TypeSave&lt;T,i&gt;
        {
             typedef Operators&lt;T,i&gt; self_t;

             friend bool operator ==(self_t const&amp; a, self_t const&amp; b)
             {
                  return a.down().equal(b.down());
             }
             friend bool operator !=(self_t const&amp; a, self_t const&amp; b)
             {
                  return not a.down().equal(b.down());
             }
        };
};
//eine zweite fähigkeit zur verdeutlichung
struct addable
{
    public:
        template&lt;typename T,int i&gt;
        struct Operators:public TypeSave&lt;T,i&gt;
        {
             typedef Operators&lt;T,i&gt; self_t;

             friend T operator +(self_t const&amp; a, self_t const&amp; b)
             {
                  T temp=a.down();
                  temp+=b.down();
                  return temp;
             }
        };
};
//ein default wert
struct Default
{
    public:
        template&lt;typename T,int i&gt;
        struct Operators{};
};
//helferklasse die die Fähigkeiten zusammenfasst. der erste Parameter ist der name von Derived, so kann man sich das tippen bei den Operatoren sparen
template&lt;class Type,class T1=Default,class T2=Default,class T3=Default,class T4=Default&gt;
struct Caps:public T1::template Operators&lt;Type,1&gt;,public T2::template Operators&lt;Type,2&gt;,
            public T3::template Operators&lt;Type,3&gt;,public T4::template Operators&lt;Type,4&gt;
{};

class Test:public Caps&lt;Test,addable,equitable&gt;
{
    public:bool equal(const Test&amp;b)const
    {
        return true;
    }
    Test&amp; operator+=(const Test&amp; other)
    {
        return *this;
    }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1313022</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313022</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sun, 24 Jun 2007 21:59:10 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 22:37:50 GMT]]></title><description><![CDATA[<p>Den Wald vor lauter Bäumen nicht gesehen? Die Mehrfachvererbung ist nur bei einem direkten Cast in den Typ des vollständigen Objektes mehrdeutig.</p>
<pre><code class="language-cpp">// static_cast ist bei nicht-virtueller Mehrfachvererbung mehrdeutig, weil nicht klar ist,
// mit welchem Subobjekt wir es zu tun haben (und aus einem ähnlichen Grunde ist staic_cast
// bei virtueller Vererbung nicht nutzbar - für einen Downcast aus einer virtuellen Basisklasse
// müssen wir den Typ des vollständigen Objekts kennen)
template&lt;class Derived,template&lt;typename&gt; class Concept&gt;
class TypeSave
{
protected:
    Derived&amp; down()
    {
        return static_cast&lt;Derived&amp;&gt;(static_cast&lt;Concept&lt;Derived&gt;&amp;&gt;(*this));
    }
    const Derived&amp; down()const
    {
        return static_cast&lt;const Derived&amp;&gt;(static_cast&lt;const Concept&lt;Derived&gt;&amp;&gt;(*this));
    }
};

template &lt;typename T&gt;
struct equitable : public TypeSave&lt;T,equitable&gt;
{
    friend bool operator ==(const equitable&amp; a, const equitable&amp; b)
    {
        return a.down().equal(b.down());
    }
    friend bool operator !=(const equitable&amp; a, const equitable&amp; b)
    {
        return not a.down().equal(b.down());
    }
};

template &lt;typename T&gt;
struct addable : public TypeSave&lt;T,addable&gt;
{
    friend T operator +(const addable&amp; a, const addable&amp; b)
    {
        T temp=a.down();
        temp+=b.down();
        return temp;
    }
};

//Defaultwerte
template&lt;typename T&gt; struct Default1 {};
template&lt;typename T&gt; struct Default2 {};
template&lt;typename T&gt; struct Default3 {};
template&lt;typename T&gt; struct Default4 {};
template&lt;typename T&gt; struct Default5 {};
template&lt;typename T&gt; struct Default6 {};
//helferklasse die die Fähigkeiten zusammenfasst. der erste Parameter ist der name von Derived, so kann man sich das tippen bei den Operatoren sparen
template&lt;class Type,template&lt;typename&gt; class T1=Default1,template&lt;typename&gt; class T2=Default2,template&lt;typename&gt; class T3=Default3,
                    template&lt;typename&gt; class T4=Default4,template&lt;typename&gt; class T5=Default5,template&lt;typename&gt; class T6=Default6&gt;
struct Caps: T1&lt;Type&gt;, T2&lt;Type&gt;, T3&lt;Type&gt;, T4&lt;Type&gt;, T5&lt;Type&gt;, T6&lt;Type&gt;
{};

class Test:public Caps&lt;Test,addable,equitable&gt;
{
    public:bool equal(const Test&amp;b)const
    {
        return true;
    }
    Test&amp; operator+=(const Test&amp; other)
    {
        return *this;
    }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1313029</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313029</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sun, 24 Jun 2007 22:37:50 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Sun, 24 Jun 2007 22:56:57 GMT]]></title><description><![CDATA[<p>Ich hab da mal zwei Links für euch:</p>
<ul>
<li><a href="http://www.boost.org/libs/preprocessor/doc/index.html" rel="nofollow">Boost.Preprocessor</a>, sehr gut für sachen wie die 6 Default-Klassen (BOOST_PP_REPEAT)</li>
<li><a href="http://fragments.wiki.sourceforge.net/" rel="nofollow">Fragments</a>, ein Projekt von rüdiger und mir, das dem Ganzen hier doch verdächtlich ähnlich ist (verdammt unfertig)</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/post/1313032</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313032</guid><dc:creator><![CDATA[Mr. N]]></dc:creator><pubDate>Sun, 24 Jun 2007 22:56:57 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Mon, 25 Jun 2007 06:44:39 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Den Wald vor lauter Bäumen nicht gesehen? Die Mehrfachvererbung ist nur bei einem direkten Cast in den Typ des vollständigen Objektes mehrdeutig.</p>
</blockquote>
<p>Nene, geht schon. Der Wald ist hier, und er besteht aus vielen schönen Bäumen ;). Deine Lösung um die mehrdeutigkeit beim casten auflösen löst das Problem schon in der weise, dass es garnichtmehr auftreten kann. durch den 2. template parameter im TypeSave ist jede Basisklasse automatisch eindeutig. Nichtsdestotrotz ist der zweite template parameter bei dir wesentlich cooler als bei mir <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Das Problem ist, dass ich nicht weis, ob static_cast die addresse eines zeigers/einer referenz ändern kann. Wenn nicht, dann setzen wir hier auf compilerspezifisches verhalten weil wir nicht garantieren können, dass alle Basisklassen auf allen Compilern die größe 0 haben und damit alle dieselbe addresse haben.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/558">@Mr.N</a> was wir wiegentlich grad machen geht stark in die richtung boost::operators.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313108</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313108</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Mon, 25 Jun 2007 06:44:39 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Mon, 25 Jun 2007 07:41:28 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>Deine Lösung um die mehrdeutigkeit beim casten auflösen löst das Problem schon in der weise, dass es garnichtmehr auftreten kann. durch den 2. template parameter im TypeSave ist jede Basisklasse automatisch eindeutig.</p>
</blockquote>
<p>Stimt. Ursprünglich wollte ich das noch anders machen:</p>
<pre><code class="language-cpp">template&lt;class Derived&gt;
class TypeSave
{
protected:
    template&lt;template&lt;typename&gt; class Concept&gt;
    static Derived&amp; down(Concept&lt;Derived&gt;&amp; x)
    {
        return static_cast&lt;Derived&amp;&gt;(x);
    }
    template&lt;template&lt;typename&gt; class Concept&gt;
    const Derived&amp; down(const Concept&lt;Derived&gt;&amp; x)
    {
        return static_cast&lt;const Derived&amp;&gt;(x);
    }
};
template &lt;typename T&gt;
struct equitable : public TypeSave&lt;T&gt;
{
    friend bool operator ==(const equitable&amp; a, const equitable&amp; b)
    {
        return a.down(a).equal(b.down(b));
    }
    friend bool operator !=(const equitable&amp; a, const equitable&amp; b)
    {
        return not a.down(a).equal(b.down(b));
    }
};
</code></pre>
<p>Ist aber auch nicht wirklich besser.</p>
<blockquote>
<p>Das Problem ist, dass ich nicht weis, ob static_cast die addresse eines zeigers/einer referenz ändern kann. Wenn nicht, dann setzen wir hier auf compilerspezifisches verhalten weil wir nicht garantieren können, dass alle Basisklassen auf allen Compilern die größe 0 haben und damit alle dieselbe addresse haben.</p>
</blockquote>
<p>Inwiefern ist das ein Problem? static_cast kann die Adresse ändern, wo nötig, wenn die entsprechenden Informationen zur Verfügung stehen (bei virtueller Vererbnung nicht der Fall, da es keine Möglichkeit gibt, dem Compiler zu sagen, dass der Zieltyp der Typ des kompletten Objekts ist). Bei Mehrfachvererbung mit nichtleeren Basisklassen ist das ganz zwangsläufig der Fall. Andererseits funktioniert die EBO in der Regel überhaupt nicht mit Mehrfachvererbung (denn zwei verschiedene Objekte (die nicht jeweils Teil des anderen sind) können während ihrer Lebenszeit nicht die gleiche Adresse haben), was generell ein Problem bei dieser Art von Komposition ist. Das kriegt man weg, wenn man in Einfachvererbung transformiert, dann betsteht wieder ein Problem, dass die Anzahl der Templateinstantiierungen explodiert. Ist alles nicht so ganz das Wahre.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313137</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313137</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 25 Jun 2007 07:41:28 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Mon, 25 Jun 2007 10:06:02 GMT]]></title><description><![CDATA[<p>Ich denke, einfachvererbung ist wirklich der beste Weg:</p>
<pre><code class="language-cpp">template&lt;class Derive&gt;
class TypeSave
{
    protected:
        typedef Derive Derived;
        Derived&amp; down()
        {
             return static_cast&lt;Derived&amp;&gt;(*this);
        }
        const Derived&amp; down()const
        {
             return static_cast&lt;const Derived&amp;&gt;(*this);
        }
};
template&lt;class Base&gt;
struct Default:public Base{};

//geht sicherlich schöner
template&lt;
    class Type,
    template&lt;class&gt;class T1=Default,
    template&lt;class&gt;class T2=Default,
    template&lt;class&gt;class T3=Default,
    template&lt;class&gt;class T4=Default,
    template&lt;class&gt;class T5=Default,
    template&lt;class&gt;class T6=Default
&gt;
class Caps:public T1&lt;T2&lt;T3&lt;T4&lt;T5&lt;T6&lt;TypeSave&lt;Type&gt; &gt; &gt; &gt; &gt; &gt; &gt;{};

template &lt;class Base&gt;
struct equitable : public Base
{
    friend bool operator ==(const equitable&amp; a, const equitable&amp; b)
    {
        return a.down().equal(b.down());
    }
    friend bool operator !=(const equitable&amp; a, const equitable&amp; b)
    {
        return not a.down().equal(b.down());
    }
};
template&lt;class Base&gt;
struct addable:public Base
{

    friend typename Base::Derived operator +(const addable&amp; a,const addable&amp; b)
    {
        typename Base::Derived temp=a.down();
        temp+=b.down();
        return temp;
    }
};

class Test:public Caps&lt;Test,addable,equitable&gt;
{
    public:bool equal(const Test&amp;b)const
    {
        return true;
    }
    Test&amp; operator+=(const Test&amp; other)
    {
        return *this;
    }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1313214</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313214</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Mon, 25 Jun 2007 10:06:02 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Mon, 25 Jun 2007 10:44:55 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/558">@Mr.N</a> was wir wiegentlich grad machen geht stark in die richtung boost::operators.</p>
</blockquote>
<p>Mag sein. Mit dem Einfachvererbungszeug seid ihr jetzt allerdings bei der Architektur von Fragments angelangt, wobei fragments (noch) kein down() hat. Nehmen wir mal an, es gäbe down (und derived), dann sähe addable etwa so aus:</p>
<pre><code class="language-cpp">struct addable {
  // ich benutze die concept+require maschinerie mal _nicht_
  typedef boost::mpl::vector0&lt;&gt; concept;

  template&lt;typename Before, typename&gt;
  struct fragment : Before {
    typename Before::derived operator+(fragment const &amp;o) const {
      typename Before::derived tmp(*this);
      tmp += o;
      return tmp;
    }
  };
};

combiner&lt;addable, ...&gt; x, y, z;
...
x = y + z;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1313229</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313229</guid><dc:creator><![CDATA[Mr. N]]></dc:creator><pubDate>Mon, 25 Jun 2007 10:44:55 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Mon, 25 Jun 2007 17:25:26 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/558">@Mr.N</a> was wir wiegentlich grad machen geht stark in die richtung boost::operators.</p>
</blockquote>
<p>Das war eigentlich eher weniger mein ursprünglicher Sinn. Wenn schon, dann müsste man es umgekehrt sagen: boost::operators geht in Richtung des Haskell-Frameworks. Das &quot;besondere&quot; an diesem Code (im Gegensatz zu b:<img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /> ist ja, dass die Klasse Equitable gewissermaßen den C++0x-Begriff der Concept Maps vorausnimmt, indem *beide* Operatoren ('==' und '!=') sowohl deklariert als auch implementiert werden.</p>
<p>-- Letztendlich ging es mir dabei aber um ein Proof of Concept. Ich arbeite (schon seit geraumer Zeit) an einer eigenen, generischen Programmiersprache, die allerdings vom Ansatz her kaum etwas mit C++ gemein hat. Leider ist die Typ-Semantik dieser Programmiersprache verdammt komplex und ich war mir nicht hundertprozentig sicher, ob das überhaupt umsetzbar wäre (ich weiß, mathematische Beweisbarkeit ... aber so'nen Beweis zusammenzubasteln ist auch nicht so einfach). Dieser Code hier ist aber letztendlich der Beweis, dass es klappt. Die Klasse 'TypeSafe' ist dabei aber ziemlich egal, das ist ja letztendlich nur ein kleines Hilfsmittel, um die Syntax des Casts zu verschönern.</p>
<p>Trotzdem ist es auf jeden Fall interessant zu sehen, auf was für Ideen ihr da so kommt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313551</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Mon, 25 Jun 2007 17:25:26 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Mon, 25 Jun 2007 20:20:40 GMT]]></title><description><![CDATA[<p>was hast du dir da denn bei der sprache vorgestellt? kann man sich vielleicht ein beispiel anschauen, wie das aussehen soll? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313645</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313645</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Mon, 25 Jun 2007 20:20:40 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Mon, 25 Jun 2007 21:13:47 GMT]]></title><description><![CDATA[<p>Ach otze, gerade wo du schon hier bist :). Warst du nicht der jenige der ein GUI-Toolkit am entwickeln war, wenn ja wie siehts damit aus ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313682</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313682</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 25 Jun 2007 21:13:47 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Mon, 25 Jun 2007 21:30:30 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>was hast du dir da denn bei der sprache vorgestellt? kann man sich vielleicht ein beispiel anschauen, wie das aussehen soll? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
</blockquote>
<p>Oh herrjemine. Ich tyrannisiere schon eine andere Community damit. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";-)"
      alt="😉"
    /></p>
<p>Die Sprache hat den Codenamen &quot;Caliph&quot; und soll halt im wesentlichen eine Abstraktion für generische Programmierung *ohne* Laufzeit-Overhead bieten. Dementsprechend also ähnlich wie C++. Der große Unterschied zu C++ ist, neben der fundamental anderen Syntax, die Erweiterbarkeit der Klassen sowie die Namensbindung. Beispielsweise würde der Aufruf 'Length(x)' eine statische Methode 'Length' für das Objekt 'x' aufrufen statt einer freien Funktion. 'x.Length()' wäre dementsprechend eine nicht-statische Methode.</p>
<p>Momentan habe ich kein Material zu Caliph online. Ich arbeite gerade an ner FAQ, die dauert aber wohl noch ein Weilchen aufgrund von Hardware-Schwierigkeiten.</p>
<p>Der Beispielcode könnte z.B. so aussehen:</p>
<pre><code>typeclass Equitable
    operator static =(a as Equitable, b as Equitable) as bool := not a != b
    operator static !=(a as Equitable, b as Equitable) as bool := not a = b
end

class String
    var private value as Array[Char]
    # ... Zeugs ...
    property public get Length as int := value.Length
end

instance String of Equitable
    operator static =(a as String, b as String) as bool
        return
            a.Length = b.Length and
            Zip(a, b, lambda(x, y) := x = y).Fold(true, lambda(x, y) := x and y)
    end
end
</code></pre>
<p>Drei Besonderheiten:</p>
<p>- 'typeclass' spezifiziert ein Verhalten für eine Klasse. Eben ein Konzept.<br />
- 'instance' sorgt dafür, dass eine Klasse ein Verhalten übernimmt.<br />
- Zeile 13 ff. zeigen den funktionalen Aspekt der Sprache. Ginge natürlich wesentlich effizienter, zumal Arrays sowieso auch 'Equitable' wären und man den Aufruf also nur zu delegieren bräuchte. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";-)"
      alt="😉"
    /> (Wobei ... ein *richtig* guter Compiler mit verzögerter Auswertung könnte das optimieren.)</p>
<p>Eine kleine Besonderheit offenbart sich auch in der For-Schleife, die stets folgendermaßen aussieht (es gibt nix à la 'for i from ... to ...'):</p>
<pre><code class="language-cpp">For x in y
</code></pre>
<p>x ist hierbei ein Iterator und y ein Bereich -- das kann ein Container sein, oder eben auch ein on-the-fly generierter Zahlenbereich. Anders als in .NET oder Java wird hier aber nicht diese 'hasnext'-Methode verwendet sondern es werden die aus C++ bekannten Iteratoren implementiert. Die Sprache verfügt auch über Zeiger, allerdings handelt es sich hierbei nur um eine spezielle Implementierung des RandomAccess-Iterators.</p>
<p>Leider klaut das C++-Standardkommittee schamlos meine Ideen und mit jeder weiteren Veröffentlichung zu C++0x schrumpf der Vorsprung von Caliph. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":-("
      alt="😞"
    /> Beispielsweise waren Concepts nicht genug, nein, sie mussten gleich Concept maps einführen -- und somit prinzipiell existierende Klassen erweiterbar machen. Schon war ein großer Trumpf von Caliph dahin.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313688</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313688</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Mon, 25 Jun 2007 21:30:30 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Tue, 26 Jun 2007 07:47:50 GMT]]></title><description><![CDATA[<p>KasF schrieb:</p>
<blockquote>
<p>Ach otze, gerade wo du schon hier bist :). Warst du nicht der jenige der ein GUI-Toolkit am entwickeln war, wenn ja wie siehts damit aus ?</p>
</blockquote>
<p>Nein, das war ich (wenn du GOTT meinst). Ist zur Zeit nicht aktiv.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/5021">@Konrad</a> Rudolph: Zum Thema &quot;Equitable&quot;: <a href="http://dict.leo.org/ende?lp=ende&amp;p=/gQPU.&amp;search=equitable" rel="nofollow">Frag Leo</a> - vielleicht wäre eine andere Bezeichnung besser. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> - Ich habe &quot;equality_comparable&quot; genommen, aber so toll ist das natürlich auch nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313784</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313784</guid><dc:creator><![CDATA[Mr. N]]></dc:creator><pubDate>Tue, 26 Jun 2007 07:47:50 GMT</pubDate></item><item><title><![CDATA[Reply to Template Parameter ist ein Template on Tue, 26 Jun 2007 09:02:52 GMT]]></title><description><![CDATA[<p>Mr. N schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/5021">@Konrad</a> Rudolph: Zum Thema &quot;Equitable&quot;: <a href="http://dict.leo.org/ende?lp=ende&amp;p=/gQPU.&amp;search=equitable" rel="nofollow">Frag Leo</a> - vielleicht wäre eine andere Bezeichnung besser. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Offensichtlich. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
<p>'EqualityComparable' ist mir aber ehrlich gesagt für ein solch ubiquitäres Konzept zu lang (auch bei 'RandomAccessIterator' bekomme ich jedes Mal ne Krise aber da ist mir auch noch nix kürzeres eingefallen). Eventuell mache ich's wie in Haskell und verwende 'Eq', 'Ord' etc. -- Abkürzungen finde ich eigentlich aber auch nicht so besonders toll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1313824</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1313824</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Tue, 26 Jun 2007 09:02:52 GMT</pubDate></item></channel></rss>