<?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[Kommutativität von Operatorüberladungen ;)]]></title><description><![CDATA[<p>Hi,</p>
<p>schreibe gerade an einer templatebasierten Matrizen-Klasse und möchte die Multiplikation mit einem Skalar implementieren.</p>
<p>Aus früheren Versuchen weiß ich, dass eine nicht-Klassenmember Implementierung à la</p>
<pre><code class="language-cpp">/* multiplication with scalars */
template &lt;class T&gt;
Matrix&lt;T&gt; operator*( const T&amp; scalar, const Matrix&lt;T&gt;&amp; matrix );
</code></pre>
<p>Probleme bei Vererbung gibt.<br />
Insbesondere existiert ein weiteres unschönes Problem:</p>
<pre><code class="language-cpp">Matrix&lt;float&gt; A(3,3) = ...;
3*A;
</code></pre>
<p>funktioniert nicht, da er keinen entspr. Operator findet weil die 3 nicht zu 3.f gecastet wird. Ließe sich zwar mit manuellem Casting oder Implementierung von Überladungen mit anderen Datentypen realisieren, schön ist das aber nicht wirklich.<br />
Insbesondere wenn die Klasse mit selbst definierten Datentypen (Komplexe Zahlen?) umgehen können soll.</p>
<p>Daher bevorzuge ich folgende Variante:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
Matrix&lt;T&gt; Matrix&lt;T&gt;::operator*( const T&amp; scalar ) const
</code></pre>
<p>Funktioniert auch soweit einwandfrei, aber leider nur in eine Richtung.<br />
A*3 klappt, 3*A nicht.</p>
<p>Kann ich irgendwie einen Klassenmember-Operator definieren, der den Skalar als linksseitiges Argument akzeptiert?</p>
<p>Thx in advance <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/topic/239857/kommutativität-von-operatorüberladungen</link><generator>RSS for Node</generator><lastBuildDate>Tue, 22 Sep 2026 07:46:57 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/239857.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 28 Apr 2009 19:13:00 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Kommutativität von Operatorüberladungen ;) on Tue, 28 Apr 2009 19:13:00 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>schreibe gerade an einer templatebasierten Matrizen-Klasse und möchte die Multiplikation mit einem Skalar implementieren.</p>
<p>Aus früheren Versuchen weiß ich, dass eine nicht-Klassenmember Implementierung à la</p>
<pre><code class="language-cpp">/* multiplication with scalars */
template &lt;class T&gt;
Matrix&lt;T&gt; operator*( const T&amp; scalar, const Matrix&lt;T&gt;&amp; matrix );
</code></pre>
<p>Probleme bei Vererbung gibt.<br />
Insbesondere existiert ein weiteres unschönes Problem:</p>
<pre><code class="language-cpp">Matrix&lt;float&gt; A(3,3) = ...;
3*A;
</code></pre>
<p>funktioniert nicht, da er keinen entspr. Operator findet weil die 3 nicht zu 3.f gecastet wird. Ließe sich zwar mit manuellem Casting oder Implementierung von Überladungen mit anderen Datentypen realisieren, schön ist das aber nicht wirklich.<br />
Insbesondere wenn die Klasse mit selbst definierten Datentypen (Komplexe Zahlen?) umgehen können soll.</p>
<p>Daher bevorzuge ich folgende Variante:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
Matrix&lt;T&gt; Matrix&lt;T&gt;::operator*( const T&amp; scalar ) const
</code></pre>
<p>Funktioniert auch soweit einwandfrei, aber leider nur in eine Richtung.<br />
A*3 klappt, 3*A nicht.</p>
<p>Kann ich irgendwie einen Klassenmember-Operator definieren, der den Skalar als linksseitiges Argument akzeptiert?</p>
<p>Thx in advance <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/1702832</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702832</guid><dc:creator><![CDATA[hasu]]></dc:creator><pubDate>Tue, 28 Apr 2009 19:13:00 GMT</pubDate></item><item><title><![CDATA[Reply to Kommutativität von Operatorüberladungen ;) on Wed, 29 Apr 2009 08:05:59 GMT]]></title><description><![CDATA[<p>hasu schrieb:</p>
<blockquote>
<p>Kann ich irgendwie einen Klassenmember-Operator definieren, der den Skalar als linksseitiges Argument akzeptiert?</p>
</blockquote>
<p>Nein, geht nicht.</p>
<p>hasu schrieb:</p>
<blockquote>
<p>Aus früheren Versuchen weiß ich, dass eine nicht-Klassenmember Implementierung à la</p>
<pre><code class="language-cpp">/* multiplication with scalars */
template &lt;class T&gt;
Matrix&lt;T&gt; operator*( const T&amp; scalar, const Matrix&lt;T&gt;&amp; matrix );
</code></pre>
<p>Probleme bei Vererbung gibt.</p>
</blockquote>
<p>Welche Probleme sollten das sein? Wenn du von Matrix ableitest musst du für die abgeleitete Klasse die Operatoren überladen. Andererseits haben Matrizen Wertsemantik und sollten eigentlich nicht abgeleitet werden.</p>
<p>hasu schrieb:</p>
<blockquote>
<p>Insbesondere existiert ein weiteres unschönes Problem:</p>
<pre><code class="language-cpp">Matrix&lt;float&gt; A(3,3) = ...;
3*A;
</code></pre>
<p>funktioniert nicht, da er keinen entspr. Operator findet weil die 3 nicht zu 3.f gecastet wird.</p>
</blockquote>
<p>Verallgemeinere deinen Operator wie folgt:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
Matrix&lt;T&gt;&amp; Matrix&lt;T&gt;::operator*=(T const&amp; rhs) { /* Skalarmultiplikation hier iplementieren */ }

template &lt;class scalar_type, class T&gt;
Matrix&lt;T&gt; operator* (scalar_type const&amp; lhs, Matrix&lt;T&gt; const&amp; rhs)
{
  Matrix&lt;T&gt; tmp(rhs);
  tmp *= lhs;
  return tmp;
}
</code></pre>
<p>Also wie üblich op*= als Member, op* mit Hilfe von op*= implementieren. In der zweiten Zeile <code>tmp *= lhs</code> versucht der Compiler dann eine Typumwandlung von scalar_type nach T.</p>
<p>Ich kann außerdem noch die Lektüre des Artikels zur Operatorüberladung empfehlen, und evtl. interessiert dich auch boost::operators <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/1702998</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702998</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 29 Apr 2009 08:05:59 GMT</pubDate></item><item><title><![CDATA[Reply to Kommutativität von Operatorüberladungen ;) on Wed, 29 Apr 2009 11:57:12 GMT]]></title><description><![CDATA[<p>Hi, erstmal danke für die Antwort.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Welche Probleme sollten das sein? Wenn du von Matrix ableitest musst du für die abgeleitete Klasse die Operatoren überladen. Andererseits haben Matrizen Wertsemantik und sollten eigentlich nicht abgeleitet werden.</p>
</blockquote>
<p>Genau die erneut nötige Überladung der Operatoren für die Tochterklasse finde ich nervig. Es müssen alle Nichtmember-Operatoren neu geschrieben werden, was teilweise (ich hatte vorher fast alles als Nichtmember implementiert) in soviel Arbeit ausartet dass man sich die Ableitung fast ganz sparen kann.<br />
Sinn können abgeleitete Klassen m.E. dennoch haben, im Falle von Matrizen bspw. alternative Datenspeicherungsmodelle für bestimmte Matrizenklassen (Diagonal-, Tridiagonal, Dreiecks-, symmetrische Matrizen). Oder bei Vektoren, die auch im Projekt implementiert sind, lohnt eine Definition des Kreuzprodukts i.d.R. nur für dim=3.<br />
Was genau meinst du mit Wertsemantik, der Begriff sagt mir nichts.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Verallgemeinere deinen Operator wie folgt:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
Matrix&lt;T&gt;&amp; Matrix&lt;T&gt;::operator*=(T const&amp; rhs) { /* Skalarmultiplikation hier iplementieren */ }

template &lt;class scalar_type, class T&gt;
Matrix&lt;T&gt; operator* (scalar_type const&amp; lhs, Matrix&lt;T&gt; const&amp; rhs)
{
  Matrix&lt;T&gt; tmp(rhs);
  tmp *= lhs;
  return tmp;
}
</code></pre>
<p>Also wie üblich op*= als Member, op* mit Hilfe von op*= implementieren. In der zweiten Zeile <code>tmp *= lhs</code> versucht der Compiler dann eine Typumwandlung von scalar_type nach T.</p>
</blockquote>
<p>Das ist eine super Idee, danke!</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Ich kann außerdem noch die Lektüre des Artikels zur Operatorüberladung empfehlen, und evtl. interessiert dich auch boost::operators <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>Werd ich mir mal ansehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703096</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703096</guid><dc:creator><![CDATA[hasu]]></dc:creator><pubDate>Wed, 29 Apr 2009 11:57:12 GMT</pubDate></item></channel></rss>