<?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 Spezialisierung&#x2F;Instantiierung]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich will Arithmetik mit Sequenzen (DSP, programmtechnisch ähnlich Array)<br />
möglichst natürlich (mathematisch üblich) schreiben können.<br />
Dazu werden Operatoren wie *= entsprechend überladen.</p>
<p>Problem: dabei kommt es zu recht ungewöhnlichen Typmixturen.<br />
Beispiel:</p>
<pre><code class="language-cpp">Feld&amp; Feld::operator*=(Feld&amp; F);
</code></pre>
<p>Klare Sache. Aber es muss eben auch</p>
<pre><code class="language-cpp">Feld&amp; Feld::operator*=(double&amp; f);
</code></pre>
<p>gehen (Skalierung eines Vektors oder Feldes mit Skalar).<br />
Neben double kann auch float, int usw. auftreten.<br />
Auch Nichtmitglieder der Klasse gibt es, wie</p>
<pre><code class="language-cpp">Feld operator*(Feld&amp; F,double d);
Feld operator*(double d, Feld&amp; F);
</code></pre>
<p>wieder statt double auch andere skalare Typen.</p>
<p>Das alles, damit man natürlich schreiben kann:</p>
<pre><code class="language-cpp">F = 3.0*A; //literal implizit doubke
F = A*2;  // literal int
F = 2.0*A + 3.0*B;
</code></pre>
<p>Solange das nicht templatisiert ist, ist der Compiler<br />
noch gnädig. Wenn man das templatisiert, muss der Argumenttyp<br />
exakt stimmen, d.h. z.B. der zweite Ausdruck wird nicht mehr<br />
akzeptiert, denn wenn nur ein Template mit double angeboten wird,<br />
wird keine Konvertierung von int nach double gemacht, wie<br />
wenn kein Template zum Einsatz kommt. Wohlgemerkt: der<br />
Template Typ T ist kein Skalar, er bezeichnet den Typ der<br />
Sequenz.<br />
Ich habe probiert, zwei Template Typen einzuführen, T für<br />
Sequenztyp und D für die skalaren Typen. Aber ich kriege<br />
den Compiler nicht dazu, alle benötigten Funktionen anzulegen.<br />
Was funktioniert ist, den Sequenztyp zu templatisieren,<br />
aber den Skalartyp jedesmal hinzuschreiben, also:</p>
<pre><code class="language-cpp">Field&lt;T&gt;&amp; Field&lt;T&gt;::operator*=(double&amp; d);
Field&lt;T&gt;&amp; Field&lt;T&gt;::operator*=(float&amp; d);
Field&lt;T&gt;&amp; Field&lt;T&gt;::operator*=(int&amp; d);
Field&lt;T&gt;&amp; Field&lt;T&gt;::operator*=(Feld&lt;T&gt;&amp; F);
</code></pre>
<p>Für die Nichtmitglieder gibt es noch mehr Varianten. Das<br />
ist äußerst lästig.</p>
<p>Wie templatisiert man so einen Typmix aus elementaren<br />
skalaren Typen und selbstgebauten Klassen? Alle Texte,<br />
die ich konsultiert habe, machen eine solche Mischung<br />
nicht.</p>
<p>MfG<br />
Wastl</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/288192/template-spezialisierung-instantiierung</link><generator>RSS for Node</generator><lastBuildDate>Thu, 20 Aug 2026 01:27:01 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/288192.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 12 Jun 2011 11:35:55 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 11:40:51 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich will Arithmetik mit Sequenzen (DSP, programmtechnisch ähnlich Array)<br />
möglichst natürlich (mathematisch üblich) schreiben können.<br />
Dazu werden Operatoren wie *= entsprechend überladen.</p>
<p>Problem: dabei kommt es zu recht ungewöhnlichen Typmixturen.<br />
Beispiel:</p>
<pre><code class="language-cpp">Feld&amp; Feld::operator*=(Feld&amp; F);
</code></pre>
<p>Klare Sache. Aber es muss eben auch</p>
<pre><code class="language-cpp">Feld&amp; Feld::operator*=(double&amp; f);
</code></pre>
<p>gehen (Skalierung eines Vektors oder Feldes mit Skalar).<br />
Neben double kann auch float, int usw. auftreten.<br />
Auch Nichtmitglieder der Klasse gibt es, wie</p>
<pre><code class="language-cpp">Feld operator*(Feld&amp; F,double d);
Feld operator*(double d, Feld&amp; F);
</code></pre>
<p>wieder statt double auch andere skalare Typen.</p>
<p>Das alles, damit man natürlich schreiben kann:</p>
<pre><code class="language-cpp">F = 3.0*A; //literal implizit doubke
F = A*2;  // literal int
F = 2.0*A + 3.0*B;
</code></pre>
<p>Solange das nicht templatisiert ist, ist der Compiler<br />
noch gnädig. Wenn man das templatisiert, muss der Argumenttyp<br />
exakt stimmen, d.h. z.B. der zweite Ausdruck wird nicht mehr<br />
akzeptiert, denn wenn nur ein Template mit double angeboten wird,<br />
wird keine Konvertierung von int nach double gemacht, wie<br />
wenn kein Template zum Einsatz kommt. Wohlgemerkt: der<br />
Template Typ T ist kein Skalar, er bezeichnet den Typ der<br />
Sequenz.<br />
Ich habe probiert, zwei Template Typen einzuführen, T für<br />
Sequenztyp und D für die skalaren Typen. Aber ich kriege<br />
den Compiler nicht dazu, alle benötigten Funktionen anzulegen.<br />
Was funktioniert ist, den Sequenztyp zu templatisieren,<br />
aber den Skalartyp jedesmal hinzuschreiben, also:</p>
<pre><code class="language-cpp">Field&lt;T&gt;&amp; Field&lt;T&gt;::operator*=(double&amp; d);
Field&lt;T&gt;&amp; Field&lt;T&gt;::operator*=(float&amp; d);
Field&lt;T&gt;&amp; Field&lt;T&gt;::operator*=(int&amp; d);
Field&lt;T&gt;&amp; Field&lt;T&gt;::operator*=(Feld&lt;T&gt;&amp; F);
</code></pre>
<p>Für die Nichtmitglieder gibt es noch mehr Varianten. Das<br />
ist äußerst lästig.</p>
<p>Wie templatisiert man so einen Typmix aus elementaren<br />
skalaren Typen und selbstgebauten Klassen? Alle Texte,<br />
die ich konsultiert habe, machen eine solche Mischung<br />
nicht.</p>
<p>MfG<br />
Wastl</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077015</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077015</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 12 Jun 2011 11:40:51 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 11:47:43 GMT]]></title><description><![CDATA[<p>Ich versteh nicht ganz,</p>
<pre><code class="language-cpp">Feld operator*(Feld&amp; F,double d);
</code></pre>
<p>sollte doch mit float, int, etc. funktionieren!? Ansonsten eben</p>
<pre><code class="language-cpp">template &lt;typename D&gt;
Feld operator*(Feld&amp; F, D d);
</code></pre>
<p>Oder willst du dass dein Feld autom. umgewandelt wird? Prinzipiell ist es von Vorteil solche Operatoren als freie Funktionen und nicht als Memberfunktionen anzulegen da dann für beide Parameter des Ausdrucks Konvertierungen angewandt werden können.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077018</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077018</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Sun, 12 Jun 2011 11:47:43 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 12:05:24 GMT]]></title><description><![CDATA[<p>Sagte ich doch, dass das noch funktioniert. In dem zuerst von Dir genannten Beispiel ist noch nichts templatisiert. Wie ich sage funktioniert das noch, weil der Compilier dann noch implizite Typkonvertierungen für eingebaute Skalare vornimmt und ja noch keine Funktionen aus Templates erzeugt werden müssen.<br />
Sobald die Sache aber templatisiert ist, ist damit Schluss. Dein Beispiel ist templatisiert, aber nicht das, was ich möchte. Bei mit soll das Feld templatisiert sein, die Skalare dann irgendwie dazu. Bei Dir ist es genau umgekehrt.</p>
<pre><code class="language-cpp">template&lt;T&gt; class Feld
{
...
    Feld(int n);
...
    Feld&amp; operator*=(const Feld&lt;T&gt;&amp; F);
    Feld&amp; operator*=(const double&amp; d); 
    Feld&amp; operator*=(const float&amp; d);     
    Feld&amp; operator*=(const long double&amp; d); 
    Feld&amp; operator*=(const int&amp; d); 
    Feld&amp; operator*=(const uint32&amp; d); 
...
};
</code></pre>
<p>Wenn ich die verschiedenen Sklartypen nicht explizit<br />
ausschreibe, also vorsehe, dann kann der Linker die<br />
hinterher nicht finden, wenn sie gebraucht werden.<br />
Die Sache wird dadurch noch interessanter, als bei</p>
<pre><code class="language-cpp">Feld&amp; operator*=(const Feld&lt;T&gt;&amp; F);
</code></pre>
<p>klarerweiser ein anderer Algorithmus zum Einsatz<br />
kommen muss als bei skalaren Typen wie</p>
<pre><code class="language-cpp">Feld&amp; operator*=(const double&amp; d);
</code></pre>
<p>Der Grundtyp von Feld T kann sein:<br />
Real: float, double, long double.<br />
Komplex: dito.</p>
<p>Wastl</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077023</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077023</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 12 Jun 2011 12:05:24 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 12:03:39 GMT]]></title><description><![CDATA[<p>D.h. du willst eigentlich sowas:</p>
<pre><code class="language-cpp">template &lt;typename U, typename V&gt; 
Feld&lt;U&gt; operator *(Feld&lt;U&gt;&amp; F, V d);
</code></pre>
<p>!? Ich versteh immer noch nicht wirklich was jetzt genau dein Problem ist <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077027</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077027</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Sun, 12 Jun 2011 12:03:39 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 12:09:15 GMT]]></title><description><![CDATA[<p>ja, so ein Template mit 2 Parametern habe ich versucht.<br />
Erfolglos. Tschuldigung, ich habe meine Anforderung oben<br />
noch einmal weiter präzisiert.<br />
Problematisch ist, dass ich zwei Algorithmen verwenden muss,<br />
einen für Skalare und einen für Felder.<br />
Templates machen aber immer dasselbe, setzen nur andere<br />
Werte ein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077036</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077036</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 12 Jun 2011 12:09:15 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 12:27:24 GMT]]></title><description><![CDATA[<p>wastl schrieb:</p>
<blockquote>
<p>ja, so ein Template mit 2 Parametern habe ich versucht.<br />
Erfolglos.</p>
</blockquote>
<p>Und &quot;erfolglos&quot; bedeutet genau was?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077043</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077043</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Sun, 12 Jun 2011 12:27:24 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 12:56:41 GMT]]></title><description><![CDATA[<p>1. Was ist das Problem an der Konvertierung nach double?<br />
2. Es geht, Feld als Feld-Typ zu interpretieren und alles andere als Zahlen. Das sähe dann so aus:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; operator*(Feld const &amp;first, T const &amp;second);
template&lt;typename T&gt; operator*(T const &amp;first, Feld const &amp;second);
Feld &amp;Feld::operator*(Feld const &amp;first, Feld const &amp;second);
</code></pre>
<p>3. Du kannst natürlich auch noch den skalaren Typ, der intern von Feld verwendet wird, templatisieren. Willst du das?<br />
4. Du kannst auch mit einem komplizierten Verfahren den übergebenen Typ bei deinem Mal-Operator unterschiedlich behandeln, abhängig davon, ob er eine isfield()-Methode besitzt oder nicht usw...</p>
<p>Mach doch mal ein Anwenderbeispiel, damit wir verstehen, was du genau brauchst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077062</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077062</guid><dc:creator><![CDATA[wxSkip]]></dc:creator><pubDate>Sun, 12 Jun 2011 12:56:41 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 13:49:15 GMT]]></title><description><![CDATA[<p>Deklariere und definiere operator*(const Feld F&lt;T&gt;&amp;, double skalar&lt;) als friend von der Templateklasse Feld und innerhalb dieser.</p>
<p>Etwa so:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class Feld
{
typedef Feld self;
public:

//...

friend self operator*(const self&amp; F, double skalar)
{
  self result(F);
  for(int i = 0; i &lt; F.size(); ++i)
    result[i] *= skalar;

  return result;
}

//...
};
</code></pre>
<p>ps: wobei ich für eine Skalarmultiplikation nur den operator*(double, const Feld&amp;); anbieten würde. Andersrum sieht das komisch aus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077077</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077077</guid><dc:creator><![CDATA[bmario]]></dc:creator><pubDate>Sun, 12 Jun 2011 13:49:15 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 14:00:33 GMT]]></title><description><![CDATA[<p>bmario schrieb:</p>
<blockquote>
<p>Deklariere und definiere operator*(const Feld F&lt;T&gt;&amp;, double skalar&lt;) als friend von der Templateklasse Feld und innerhalb dieser.</p>
</blockquote>
<p>Nein. Lass die globalen <code>operator*</code> auf den Member <code>operator*=</code> zurückgreifen.</p>
<pre><code class="language-cpp">Feld&amp; Feld::operator*= (double rhs);
Feld  operator* (Feld lhs, double rhs);
Feld  operator* (double lhs, Feld rhs);
</code></pre>
<p>bmario schrieb:</p>
<blockquote>
<p>ps: wobei ich für eine Skalarmultiplikation nur den operator*(double, const Feld&amp;); anbieten würde. Andersrum sieht das komisch aus.</p>
</blockquote>
<p>&quot;Komisch aussehen&quot; ist kein Grund, die Kommutativität der Multiplikation (die zumindest hier vorhanden ist, falls <code>Feld</code> eine Art Vektor ist) zu verletzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077085</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077085</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 12 Jun 2011 14:00:33 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 14:12:28 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>bmario schrieb:</p>
<blockquote>
<p>Deklariere und definiere operator*(const Feld F&lt;T&gt;&amp;, double skalar&lt;) als friend von der Templateklasse Feld und innerhalb dieser.</p>
</blockquote>
<p>Nein. Lass die globalen <code>operator*</code> auf den Member <code>operator*=</code> zurückgreifen.</p>
<pre><code class="language-cpp">Feld&amp; Feld::operator*= (double rhs);
Feld  operator* (Feld lhs, double rhs);
Feld  operator* (double lhs, Feld rhs);
</code></pre>
</blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>bmario schrieb:</p>
<blockquote>
<p>ps: wobei ich für eine Skalarmultiplikation nur den operator*(double, const Feld&amp;); anbieten würde. Andersrum sieht das komisch aus.</p>
</blockquote>
<p>&quot;Komisch aussehen&quot; ist kein Grund, die Kommutativität der Multiplikation (die zumindest hier vorhanden ist, falls <code>Feld</code> eine Art Vektor ist) zu verletzen.</p>
</blockquote>
<p>Mit &quot;komisch aussehen&quot; meinte ich, dass die Skalarmultiplikation eines Vektorraumes im Allgemeinen eben nicht kommutativ ist. Allerdings gibt es Spezialfälle, für welche dies gilt, z.B. für den R-Vektorraum R^1.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077094</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077094</guid><dc:creator><![CDATA[bmario]]></dc:creator><pubDate>Sun, 12 Jun 2011 14:12:28 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Mon, 13 Jun 2011 18:49:23 GMT]]></title><description><![CDATA[<p>der Ärger geht schon mit Literalen los. Literale werden<br />
offenbar bei der Template-Instantiation anders behandelt<br />
als Variablen. Z.B.</p>
<pre><code class="language-cpp">template&lt;class T, class D&gt;
feld&lt;T&gt; operator+(const feld&lt;T&gt;&amp; Lhs,const D&amp; rhs);
template&lt;class T, class D&gt;
feld&lt;T&gt; operator+(const feld&lt;T&gt;&amp; Lhs,const D&amp; rhs)
{
   feld&lt;T&gt; Tmp;
   Tmp += Lhs;
   Tmp += rhs;
   return Tmp;
}
...

int main()
{

    feld&lt;float&gt; A(10);
    int i=0;  
    A+i; // geht, Variable, Funktionsinstantiation wird angelegt
    A+3.0;  // geht nicht, Literal
    A+1;  // geht nicht, Literal

}
</code></pre>
<p>Oberstes Ziel für mich ist, dass Ausdrücke natürlich geschrieben<br />
werden können. Es reichst schon, dass die Mathematik kompliziert<br />
ist, da brauche ich nicht noch eine nicht intuitive Syntax.</p>
<p>Ich werde wohl Templates für den Feld-Typ verwenden, aber<br />
für die skalaren Typen das Gemeinsame in eine Unterfunktion<br />
packen und das Besondere vielleicht per Perl-Script aus<br />
einem Prototypen auswalzen.</p>
<p>Wenn die Tyen, die überhaupt benötigt werden, sehr überschaubar<br />
sind und wenn sehr verschiedene Algorithmen je Typ<br />
angewendet werden, dann verlieren Templates sehr stark an<br />
Attraktivität. Für die Container der STL funktioniert das,<br />
aber z. B. für eine FFT, die je nach Argumenttyp optimierte<br />
Algorithmen loslässt, ist das eben nicht so. <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="😞"
    /></p>
<p>Übrigens: wie kann eine Funktion den Typ des Arguments erkennen?</p>
<p>Wastl</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077220</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077220</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Mon, 13 Jun 2011 18:49:23 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 18:00:51 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">,D const&amp; rhs)
</code></pre>
<p>Sonst klappt's nicht bei r-values.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077225</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077225</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sun, 12 Jun 2011 18:00:51 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Sun, 12 Jun 2011 19:23:30 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/26631">@wastl</a>: Eine Funktion &quot;erkennt&quot; den Typ des Templates nicht, für jeden Typ wird eine eigene Funktion vom Compiler generiert, deswegen muss der Typ auch zur Compilezeit bekannt sein. Übrigens klingt das, was du da sagst, einerseits unverständlich und andererseits so, als ob man dir durchaus noch helfen könnte, deshalb bitte ich dich nochmal, das Zeug mal genau zu erklären. Ein Funktionsbeispiel mit allen Features hast du auch noch nicht gemacht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077252</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077252</guid><dc:creator><![CDATA[wxSkip]]></dc:creator><pubDate>Sun, 12 Jun 2011 19:23:30 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Mon, 13 Jun 2011 19:01:19 GMT]]></title><description><![CDATA[<p>im letzten Beispiel habe ich ein Beispiel<br />
für den Operator &quot;+&quot; angegeben.<br />
Der Compiler bildet die richtige Funktion<br />
aus dem Template, bzw. casted, wenn die Argumente<br />
Variablen sind. Bei Literalen funktioniert<br />
das Beispiel nicht. Also habe ich doch<br />
ein Beispiel gegeben. (die const habe ich gefixt).</p>
<p>Arithmetische Operationen enthalten i.d.R.<br />
Literale, so dass eine natürliche Schreibweise<br />
dadurch nicht möglich ist.</p>
<p>Das ist schon ein nicht unerhebliches Teilproblem<br />
des Ganzen und sollte zunächst betrachtet werden.</p>
<p>I.d.R. werden immer Templates der Sorte</p>
<pre><code class="language-cpp">template&lt;T&gt; Feld&lt;T&gt;&amp; Feld&lt;T&gt;::operator+=(Feld&lt;T&gt;&amp; Rhs);
</code></pre>
<p>betrachtet, für die gar kein Problem auftritt, weil<br />
der Typ von Rhs mit dem Feldtyp übereinstimmt.<br />
Wenn die Situation asymmetrisch wird, beginnen die<br />
Probleme:</p>
<pre><code class="language-cpp">template&lt;T&gt; Feld&lt;T&gt;&amp; Feld&lt;T&gt;::operator+=(TYPE&amp; Rhs);
</code></pre>
<p>wobei Type irgendein skalarer Typ ist, eine Lösung<br />
ist gesucht, die solche Skalaren Typen allesamt<br />
abdeckt und auch mit Literalen zurecht kommt.<br />
Dito für Nichtmitgliedfunktionen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2077646</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077646</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Mon, 13 Jun 2011 19:01:19 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Tue, 14 Jun 2011 09:01:57 GMT]]></title><description><![CDATA[<p>Am besten du machst die Übergabe immer da, wo es sinnvoll ist, als const-Referenz.<br />
Auf Literale und temporäre Ausdrücke können keine veränderlichen Referenzen genommen werden.</p>
<p>z.B.</p>
<pre><code class="language-cpp">class Vector;
const Vector operator+(Vector&amp; lhs, Vector&amp; rhs);

Vector v,w,z;
//...
Vector sum=v+w+z; //Fehler, es wird eine Referenz auf ein temporäres Objekt erzeugt
Vector sum2 = sum + 2; //Fehler, es wird eine Referenz auf ein Literal erzeugt
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2077834</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2077834</guid><dc:creator><![CDATA[bmario]]></dc:creator><pubDate>Tue, 14 Jun 2011 09:01:57 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Tue, 14 Jun 2011 17:50:17 GMT]]></title><description><![CDATA[<p>Das mit den const ist schon klar, bloß hier<br />
gespart beim Tippen.</p>
<p>Ich habe das allgemein jetzt so gelöst:</p>
<pre><code class="language-cpp">template&lt;T&gt; class Feld
{
public:
    Feld(int n);
    ~Feld();

    Feld&amp; operator+=(const Feld&amp; Rhs);   // das ist der Normalfall, selber Typ
    Feld&amp; operator+=(const double&amp; rhs); // damit gehen Skalare und auch Literale
    Feld&amp; operator+=(const float&amp; rhs);  // damit gehen Skalare 
    Feld&amp; operator+=(const int&amp; rhs);    // damit gehen Skalare und auch Literale
    Feld&amp; operator+=(const uint32&amp; rhs); // damit gehen Skalare 
...
};
</code></pre>
<p>Für die Nichtmitglieder entsprechend, da gibt es noch mehr Varianten:</p>
<pre><code class="language-cpp">Feld&lt;T&gt; operator+(const Feld&lt;T&gt;&amp; Lhs, const Feld&lt;T&gt;&amp; Rhs);
Feld&lt;T&gt; operator+(const Feld&lt;T&gt;&amp; Lhs, const double&amp; rhs);
Feld&lt;T&gt; operator+(const Feld&lt;T&gt;&amp; Lhs, const float&amp; rhs);
Feld&lt;T&gt; operator+(const Feld&lt;T&gt;&amp; Lhs, const int&amp; rhs);
Feld&lt;T&gt; operator+(const Feld&lt;T&gt;&amp; Lhs, const uint32&amp; rhs);
Feld&lt;T&gt; operator+(const double&amp; lhs, const Feld&lt;T&gt;&amp; Rhs);
Feld&lt;T&gt; operator+(const float&amp; lhs,  const Feld&lt;T&gt;&amp; Rhs);
Feld&lt;T&gt; operator+(const int&amp; lhs,    const Feld&lt;T&gt;&amp; Rhs);
Feld&lt;T&gt; operator+(const uint32&amp; lhs, const Feld&lt;T&gt;&amp; Rhs);
</code></pre>
<p>Schön ist auch &quot;-&quot; oder &quot;/&quot;, weil nicht kommutativ, also dann<br />
3 Algorithmen: für Feld&lt;T&gt;, für Skalar links und Skalar rechts.<br />
Na und wenn T komplexe Zahlen repräsentiert, dann machen<br />
viele Kombinationen wenig Sinn. Spezialisierung zur<br />
Elimination solcher Varianten ??</p>
<p>Ich präzisiere meine Frage jetzt: wie kann ich die mehrfache<br />
Anlage für jeden Operator sparen? Dass es für einen Vektor<br />
anders ist als für einen Skalar, das ist ja klar, anderer Code.<br />
Aber wenigstens die skalaren Typen sollte man doch irgendwie<br />
zusammen erschlagen können.</p>
<pre><code class="language-cpp">template&lt;T,D&gt;
</code></pre>
<p>Konstruktionen helfen nicht bei Literalen und auch sonst,<br />
auch kam es zum Überladen von Operatoren per Mehrfachinstantiation<br />
durch den Compiler. Das habe ich schon probiert.<br />
Das aus-x-en wie oben funktioniert, das weiß ich sicher.</p>
<p>Man muss es probieren, denn vieles funktioniert in der<br />
Praxis doch nicht, z. B. wegen der impliziten Template-Auswerte-Regeln.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2078150</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2078150</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Tue, 14 Jun 2011 17:50:17 GMT</pubDate></item><item><title><![CDATA[Reply to Template Spezialisierung&#x2F;Instantiierung on Tue, 14 Jun 2011 18:10:57 GMT]]></title><description><![CDATA[<p>Ich kann dein Problem nicht nachvollziehen?</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;cassert&gt;

template &lt;typename T&gt;
class vector {
public:
	explicit vector(int size) : data(size) {}

	const T&amp; operator[](int n) const
	{
		return data[n];
	}

	T&amp; operator[](int n)
	{
		return data[n];
	}

	int num_rows() const
	{
		return data.size();
	}

	friend const vector&lt;T&gt; operator+(const vector&lt;T&gt;&amp; lhs, const vector&lt;T&gt;&amp; rhs)
	{
		assert(lhs.num_rows() == rhs.num_rows());

		vector&lt;T&gt; result(lhs.num_rows());

		for (int i=0; i&lt;lhs.num_rows(); i++) {
			result[i] = lhs[i] + rhs[i];
		}

		return result;
	}

	template &lt;typename D&gt;
	friend const vector&lt;T&gt; operator+(const vector&lt;T&gt;&amp; lhs, const D&amp; rhs)
	{		
		vector&lt;T&gt; result(lhs.num_rows());

		for (int i=0; i&lt;lhs.num_rows(); i++) {
			result[i] = lhs[i] + rhs;
		}

		return result;
	}	

	template &lt;typename D&gt;
	friend const vector&lt;T&gt; operator+(const D&amp; lhs, const vector&lt;T&gt;&amp; rhs)
	{		
		vector&lt;T&gt; result(rhs.num_rows());

		for (int i=0; i&lt;rhs.num_rows(); i++) {
			result[i] = lhs + rhs[i];
		}

		return result;
	}	

private:
	vector();
	std::vector&lt;T&gt; data;
};

template &lt;typename T&gt;
std::ostream&amp; operator&lt;&lt;(std::ostream&amp; s, const vector&lt;T&gt;&amp; v)
{
	s &lt;&lt; &quot;[ &quot;;
	for (int i=0; i&lt;v.num_rows()-1; i++) {
		s &lt;&lt; v[i] &lt;&lt; &quot;, &quot;;
	}

	s &lt;&lt; v[v.num_rows()-1] &lt;&lt; &quot;]\n&quot;;

	return s;
}

int main (int argc, char * const argv[]) {

	vector&lt;double&gt; a(3),b(3);

	a[0] = 5;
	a[2] = 7;

	b[1] = 3;

	std::cout &lt;&lt; a &lt;&lt; b;

	std::cout &lt;&lt; a+b &lt;&lt; a+5 &lt;&lt; 5+a &lt;&lt; 2.5 + a + 2.5 &lt;&lt; a+5.0 &lt;&lt; 0. + a + 0L + 5U;

    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2078162</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2078162</guid><dc:creator><![CDATA[bmario]]></dc:creator><pubDate>Tue, 14 Jun 2011 18:10:57 GMT</pubDate></item></channel></rss>