<?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[Templatefunktion mit nicht-Template Freund]]></title><description><![CDATA[<p>Ich versuche gerade ein einem fremden Code der etwas älter und mir freundlicherweise zur Verfügung gestellt worden ist ein paar Compilerwarnungen zu entfernen, so denn auch diese:</p>
<blockquote>
<p>Warnung: »friend«-Deklaration »std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const SO&lt;T&gt;&amp;)« deklariert eine Nicht-Template-Funktion</p>
</blockquote>
<p>Der Code sieht wie folgt aus:</p>
<pre><code class="language-cpp">template&lt;class T&gt; class SO {

// ... vieles was nicht beanstandet wird

// der böse Operator:
friend inline ostream&amp; operator&lt;&lt; (ostream&amp; os, const SO&lt;T&gt;&amp; other);
};
</code></pre>
<p>Soweit so gut, jetzt dachte ich, das müsste einfach nur ein ändern der Zeile in:</p>
<pre><code class="language-cpp">friend inline ostream&amp; operator&lt;&lt; &lt;&gt;(ostream&amp; os, const SO&lt;T&gt;&amp; other);
</code></pre>
<p>sein. Was mir auch die unheimliche Verbesserung bringt, dass ich nun keine Warnung mehr habe, sondern einen Fehler:</p>
<blockquote>
<p>Fehler: Deklaration von »operator&lt;&lt;« als Nicht-Funktion</p>
</blockquote>
<p>Autsch! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
<p>Nachgeschlagen bei einem gewissen Herrn Stroustrup - S.370 Kapitel 13.6... der macht es vermeintlich auch nicht anders...<br />
Aber anscheinend ja doch, oder der GCC machts anders... oder... ich weiß es nicht.</p>
<p>Kann mir wer sagen, wo mein Fehler liegt?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/230282/templatefunktion-mit-nicht-template-freund</link><generator>RSS for Node</generator><lastBuildDate>Fri, 25 Sep 2026 21:20:49 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/230282.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 23 Dec 2008 13:41:45 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 23 Dec 2008 13:41:45 GMT]]></title><description><![CDATA[<p>Ich versuche gerade ein einem fremden Code der etwas älter und mir freundlicherweise zur Verfügung gestellt worden ist ein paar Compilerwarnungen zu entfernen, so denn auch diese:</p>
<blockquote>
<p>Warnung: »friend«-Deklaration »std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const SO&lt;T&gt;&amp;)« deklariert eine Nicht-Template-Funktion</p>
</blockquote>
<p>Der Code sieht wie folgt aus:</p>
<pre><code class="language-cpp">template&lt;class T&gt; class SO {

// ... vieles was nicht beanstandet wird

// der böse Operator:
friend inline ostream&amp; operator&lt;&lt; (ostream&amp; os, const SO&lt;T&gt;&amp; other);
};
</code></pre>
<p>Soweit so gut, jetzt dachte ich, das müsste einfach nur ein ändern der Zeile in:</p>
<pre><code class="language-cpp">friend inline ostream&amp; operator&lt;&lt; &lt;&gt;(ostream&amp; os, const SO&lt;T&gt;&amp; other);
</code></pre>
<p>sein. Was mir auch die unheimliche Verbesserung bringt, dass ich nun keine Warnung mehr habe, sondern einen Fehler:</p>
<blockquote>
<p>Fehler: Deklaration von »operator&lt;&lt;« als Nicht-Funktion</p>
</blockquote>
<p>Autsch! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
<p>Nachgeschlagen bei einem gewissen Herrn Stroustrup - S.370 Kapitel 13.6... der macht es vermeintlich auch nicht anders...<br />
Aber anscheinend ja doch, oder der GCC machts anders... oder... ich weiß es nicht.</p>
<p>Kann mir wer sagen, wo mein Fehler liegt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1634647</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1634647</guid><dc:creator><![CDATA[Tyrfing]]></dc:creator><pubDate>Tue, 23 Dec 2008 13:41:45 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 23 Dec 2008 15:05:22 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template&lt;class T&gt; class SO {

/* ... */

friend ostream&amp; operator&lt;&lt; (ostream&amp; os, const SO&amp; other);
};

template &lt;typename T&gt;
inline ostream&amp; operator &lt;&lt; (ostream&amp; os, const T&amp; other)
{
/*..*/
}
</code></pre>
<p>allerdings sieht das so aus, als ob du <code>using namespace std;</code> in nem header verwendest?! sollte man niemals machen da man so in allen files in denen man deinen header included den namespace std nutzt - und somit das ganze konzept der namespaces kaputt macht...</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1634693</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1634693</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Tue, 23 Dec 2008 15:05:22 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Wed, 24 Dec 2008 22:20:02 GMT]]></title><description><![CDATA[<p>Erstmal frohe Weihnachten und vielen Dank für die Hilfe soweit. :xmas1:</p>
<p>Ja, das mit dem Namespace, da hast du recht.<br />
Das war vorerst erstmal eine Bequemlichkeitssache, da es sehr sehr viele Fehler beseitigt hat - der Code ist nämlich aus der Zeit vor Namespaces entstanden (ja, auch sowas gibt es noch) und ich war es leid immer wieder std:: zu tippen <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>Ich sollte das dringend entfernen, gerade auch weil ich neben der Standardbibliothek auch eine andere Bibliothek (LEDA) verwende, die bspw. auch Strings anbietet und da Probleme entstehen können.</p>
<p>Ich werde ich deinen Vorschlag demnächst ausprobieren, aktuell bin ich zeitlich etwas kurz angebunden (wie die meisten von uns, nehme ich an).</p>
<p>Vielen Dank schonmal!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1635127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1635127</guid><dc:creator><![CDATA[Tyrfing]]></dc:creator><pubDate>Wed, 24 Dec 2008 22:20:02 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Thu, 25 Dec 2008 20:09:49 GMT]]></title><description><![CDATA[<p>Tyrfing schrieb:</p>
<blockquote>
<p>Ich werde ich deinen Vorschlag demnächst ausprobieren, aktuell bin ich zeitlich etwas kurz angebunden (wie die meisten von uns, nehme ich an).</p>
</blockquote>
<p>Hmm... Ich dachte immer, dass es jz ~allen langweilig ist - aber wahrscheinlich ist mein rl einfach zu zurückgebildet ;o)</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1635473</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1635473</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 25 Dec 2008 20:09:49 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Mon, 12 Jan 2009 19:40:19 GMT]]></title><description><![CDATA[<p>So, nach einiger Zeit wieder in den Code geschaut... was man nicht alles dringenderes zu erledigen findet, wenn man eine Aufgabe hat, auf die man nicht so recht Lust hat <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>Ganz so schlimm war es mit dem <em>Using</em> dann doch nicht, ich habe nicht die <em>std</em> standardmäßig eingebunden sondern &quot;nur&quot; die <em>std::ostream</em> und einige andere Dinge - also bspw. den kritischen String nicht, wobei das habe ich nun überarbeitet.</p>
<p>Dein Änderungsvorschlag stößt aber auch nicht auf Compilersegen und ich verstehe ihn auch nicht so recht, muss ich sagen.</p>
<p>Der Compiler sagt mir dazu, dass ich eine nicht-eindeutige Referenz auf den Operator&lt;&lt; hätte und allerlei undurchsichtigen Std-Template-Fehlermeldungen *seufz*<br />
Nachtrag: Und noch schlimmer, die Fehlermeldungen kommen auch erst, nachdem er festgestellt hat, dass ich immer noch einen &quot;nicht Template Freund&quot; deklariert habe. Also scheint's mir, ich habe das Problem nicht beseitigt und ausserdem einen weiteren Fehler eingebaut.</p>
<p>Ich sag dazu erstmal folgendes:</p>
<pre><code class="language-cpp">template&lt;class T&gt; class SO {

/* ... */

friend ostream&amp; operator&lt;&lt; (ostream&amp; os, const SO&amp; other);
};

template &lt;typename T&gt;
inline ostream&amp; operator &lt;&lt; (ostream&amp; os, const T&amp; other)
{
/*..*/
}
</code></pre>
<p>Oben in der Klasse wird eine Funktion definiert, die als zweiten Parameter eine Instanz der mit T parametrisierten Klasse SO erwartet. Bei der Implementierung hingegen erwarten wir als zweiten Parameter nicht mehr eine Instanz der Klasse SO sondern eine den Typen T?!</p>
<p>Also um es konkreter zu machen, wenn es um SO&lt;int&gt; ginge, dann würde ich nun bei der Ausgabe nicht mehr die Klasse SO&lt;int&gt; erwarten, sondern direkt ein int?<br />
Klingt für mich erstmal nicht einleuchtend...</p>
<p>Nachtrag:<br />
---------</p>
<p>Also, was meines erachtens eigentlich funktionieren müsste, aber es nicht tut ist der folgende Code:</p>
<pre><code class="language-cpp">template&lt;class T&gt; class SO {
  /* ... */
  friend std::ostream&amp; operator&lt;&lt; &lt;&gt;  (std::ostream&amp;, const SO&lt;T&gt;&amp;);

private:
  T* obj_;
};
</code></pre>
<p>und dann etwas später:</p>
<pre><code class="language-cpp">template&lt;class T&gt; std::ostream&amp; operator&lt;&lt; (std::ostream&amp; os,
               const SO&lt;T&gt;&amp; other) {
  os &lt;&lt; other.obj_;
  return (os);
}
</code></pre>
<p>Was mir aber mit einem:</p>
<blockquote>
<p>Fehler: Deklaration von »operator&lt;&lt;« als Nicht-Funktion<br />
Fehler: expected »;« before »&lt;« token</p>
</blockquote>
<p>vom Compiler quitiert wird?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1644065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1644065</guid><dc:creator><![CDATA[Tyrfing]]></dc:creator><pubDate>Mon, 12 Jan 2009 19:40:19 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 13 Jan 2009 10:07:31 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>die Lösung für dein ursprüngliches Problem sollte sich durch Forward-Deklarationen lösen lassen:</p>
<pre><code class="language-cpp">template&lt;class T&gt; class SO;
template&lt;class T&gt;
std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const SO&lt;T&gt;&amp;);

template&lt;class T&gt; class SO
{
  ...
  friend std::ostream&amp; operator&lt;&lt; &lt;&gt;(std::ostream&amp;,const SO&lt;T&gt;&amp; );
};

//Definition
...
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1644386</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1644386</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Tue, 13 Jan 2009 10:07:31 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 13 Jan 2009 10:41:43 GMT]]></title><description><![CDATA[<p>Der Orginalcode ist eigentlich richtig. Ich bekomm auch keine Warnung. Vielleicht wirklich ne gcc Macke??</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1644410</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1644410</guid><dc:creator><![CDATA[David_pb]]></dc:creator><pubDate>Tue, 13 Jan 2009 10:41:43 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 13 Jan 2009 12:21:08 GMT]]></title><description><![CDATA[<p>Welchen Compiler nutzt du?</p>
<p>Der gcc 4.3 (MinGW-Portierung) warnt auf jeden Fall.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1644481</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1644481</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Tue, 13 Jan 2009 12:21:08 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 13 Jan 2009 12:22:27 GMT]]></title><description><![CDATA[<p>Visual C++ 2005 und Comeau.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1644483</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1644483</guid><dc:creator><![CDATA[David_pb]]></dc:creator><pubDate>Tue, 13 Jan 2009 12:22:27 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 13 Jan 2009 12:52:25 GMT]]></title><description><![CDATA[<p>Tatsächlich, sehr interessant. Die beiden lassen es durch <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1644509</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1644509</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Tue, 13 Jan 2009 12:52:25 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 13 Jan 2009 13:24:18 GMT]]></title><description><![CDATA[<p>Okay, ich glaube das Problem ist nun gelöst, vielen Dank an euch drei und natürlich insbesondere Aquae für den ausschlaggebenden Tipp.</p>
<p>Damit andere (oder ich selbst, wenn ich nochmal drüber falle) es auch nochmal schön nachlesen können, was geholfen hat, hier dann die korrigierte Version:</p>
<pre><code class="language-cpp">// Forward Deklaration
template&lt;class T&gt; class SO;
template&lt;class T&gt;  std::ostream&amp; operator&lt;&lt; (std::ostream&amp;, const SO&lt;T&gt;&amp;);

/* ... ... ...*/

// eigentliche Klasse mit problematischem Freund
template&lt;class T&gt; class SO {
  /* ... */
  friend std::ostream&amp; operator&lt;&lt; &lt;&gt;(std::ostream&amp; os, const SO&lt;T&gt;&amp; other);
private:
  T* obj_;
};

/* ... ... ... */

// Implementation des Freundes
template&lt;class T&gt; inline
std::ostream&amp; operator&lt;&lt; (std::ostream&amp; os,const SO&lt;T&gt;&amp; other) {
  os &lt;&lt; other.obj_;
  return (os);
}
</code></pre>
<p>Für mich dabei interessant ist, wo an welcher Stelle ich bitteschön ein &quot;&lt;&gt;&quot; einfügen musste und wo es überall nicht okay war.<br />
Zum Beispiel ganz unten in der Implementation war es nicht okay eins einzufügen, hingegen bei der Friend-Deklaration musste es stehen, sonst gab's die Warnung, die ich ursprünglich entfernen wollte.</p>
<p>Nochmals, vielen Dank!<br />
Dann mach ich mich jetzt mal auf die Socken das an diversen Stellen des Quellcodes zu überarbeiten *seufz*</p>
<p><em>Nachtrag: Jetzt ist mir doch tatsächlich das inline dabei verloren gegangen, nachgetragen.</em></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1644526</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1644526</guid><dc:creator><![CDATA[Tyrfing]]></dc:creator><pubDate>Tue, 13 Jan 2009 13:24:18 GMT</pubDate></item><item><title><![CDATA[Reply to Templatefunktion mit nicht-Template Freund on Tue, 13 Jan 2009 17:27:25 GMT]]></title><description><![CDATA[<p>Das &lt;&gt; muss in die friend-Deklaration rein, damit der Compiler weiss, dass er die Template-Version von operator&lt;&lt; benutzen soll. Er sieht ja bei Inspektion der Klasse nicht</p>
<pre><code class="language-cpp">friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const SO&lt;T&gt;&amp; other); //falls ohne &lt;&gt;
</code></pre>
<p>sondern schon den erzeugte Funktion</p>
<pre><code class="language-cpp">friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const SO&lt;int&gt;&amp; other); //Sei T = int
</code></pre>
<p>welches für ihn eine Nicht-Template-Funktion ist.</p>
<p>Mir ist jetzt nur rätselhaft, dass es tatsächlich nur mit einer Warning compiliert und gelinkt wird... schliesslich findet er doch diese Nicht-Template-Variante nirgendwo?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1644741</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1644741</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Tue, 13 Jan 2009 17:27:25 GMT</pubDate></item></channel></rss>