<?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[[solved] wieder mal: templates vs. iostream]]></title><description><![CDATA[<p>hallo,</p>
<p>jedes mal wenn ich was auf die art versuche, hab ich probleme. irgendwie kapier' ich das einfach nicht. warum geht das nicht:</p>
<pre><code class="language-cpp">namespace ns
{
	template &lt;class T&gt;
	class MyClass
	{
	private: 
		T value;

	public:
		MyClass( T i ) : value( i )		{}

		friend std::ostream &amp;operator &lt;&lt; ( std::ostream &amp;ostr, const MyClass&lt;T&gt; &amp;mc );
	};
}

template &lt;class T&gt;
std::ostream &amp;operator &lt;&lt; ( std::ostream &amp;ostr, const ns::MyClass&lt;T&gt; &amp;mc )
{
	ostr &lt;&lt; mc.value;
	return ostr;
}

int main( int argc, char **argv )
{
	ns::MyClass&lt;int&gt; mc( 10 );

	std::cout &lt;&lt; mc &lt;&lt; std::endl;
}
</code></pre>
<p>MSVC 9.0 schrieb:</p>
<blockquote>
<p>1&gt;main.obj : error LNK2019: unresolved external symbol &quot;class std::basic_ostream&lt;char,struct std::char_traits&lt;char&gt; &gt; &amp; __cdecl ns::operator&lt;&lt;(class std::basic_ostream&lt;char,struct std::char_traits&lt;char&gt; &gt; &amp;,class ns::MyClass&lt;int&gt; const &amp;)&quot; (??6ns@@YAAAV?<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>b</mi><mi>a</mi><mi>s</mi><mi>i</mi><mi>c</mi><mi mathvariant="normal">_</mi><mi>o</mi><mi>s</mi><mi>t</mi><mi>r</mi><mi>e</mi><mi>a</mi><mi>m</mi><mi mathvariant="normal">@</mi><mi>D</mi><mi>U</mi><mo>?</mo></mrow><annotation encoding="application/x-tex">basic\_ostream@DU?</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:1.00444em;vertical-align:-0.31em;"></span><span class="base textstyle uncramped"><span class="mord mathit">b</span><span class="mord mathit">a</span><span class="mord mathit">s</span><span class="mord mathit">i</span><span class="mord mathit">c</span><span class="mord mathrm" style="margin-right:0.02778em;">_</span><span class="mord mathit">o</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mord mathit" style="margin-right:0.02778em;">r</span><span class="mord mathit">e</span><span class="mord mathit">a</span><span class="mord mathit">m</span><span class="mord mathrm">@</span><span class="mord mathit" style="margin-right:0.02778em;">D</span><span class="mord mathit" style="margin-right:0.10903em;">U</span><span class="mclose">?</span></span></span></span>char_traits@D@std@@@std@@AAV12@ABV?$MyClass@H@0@@Z) referenced in function _main</p>
</blockquote>
<p>???</p>
<p>es wird offensichtlich im falschen namespace gesucht (&quot;ns::operator&lt;&lt;&quot;), aber dort gehört der operator ja auch nicht hin. wenn ich die funktionsdefinition in den namespace reinkopiere gehts genauso wenig.</p>
<p>thx,<br />
iko.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/262439/solved-wieder-mal-templates-vs-iostream</link><generator>RSS for Node</generator><lastBuildDate>Fri, 04 Sep 2026 09:17:33 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/262439.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 05 Mar 2010 23:22:24 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 10:43:32 GMT]]></title><description><![CDATA[<p>hallo,</p>
<p>jedes mal wenn ich was auf die art versuche, hab ich probleme. irgendwie kapier' ich das einfach nicht. warum geht das nicht:</p>
<pre><code class="language-cpp">namespace ns
{
	template &lt;class T&gt;
	class MyClass
	{
	private: 
		T value;

	public:
		MyClass( T i ) : value( i )		{}

		friend std::ostream &amp;operator &lt;&lt; ( std::ostream &amp;ostr, const MyClass&lt;T&gt; &amp;mc );
	};
}

template &lt;class T&gt;
std::ostream &amp;operator &lt;&lt; ( std::ostream &amp;ostr, const ns::MyClass&lt;T&gt; &amp;mc )
{
	ostr &lt;&lt; mc.value;
	return ostr;
}

int main( int argc, char **argv )
{
	ns::MyClass&lt;int&gt; mc( 10 );

	std::cout &lt;&lt; mc &lt;&lt; std::endl;
}
</code></pre>
<p>MSVC 9.0 schrieb:</p>
<blockquote>
<p>1&gt;main.obj : error LNK2019: unresolved external symbol &quot;class std::basic_ostream&lt;char,struct std::char_traits&lt;char&gt; &gt; &amp; __cdecl ns::operator&lt;&lt;(class std::basic_ostream&lt;char,struct std::char_traits&lt;char&gt; &gt; &amp;,class ns::MyClass&lt;int&gt; const &amp;)&quot; (??6ns@@YAAAV?<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>b</mi><mi>a</mi><mi>s</mi><mi>i</mi><mi>c</mi><mi mathvariant="normal">_</mi><mi>o</mi><mi>s</mi><mi>t</mi><mi>r</mi><mi>e</mi><mi>a</mi><mi>m</mi><mi mathvariant="normal">@</mi><mi>D</mi><mi>U</mi><mo>?</mo></mrow><annotation encoding="application/x-tex">basic\_ostream@DU?</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:1.00444em;vertical-align:-0.31em;"></span><span class="base textstyle uncramped"><span class="mord mathit">b</span><span class="mord mathit">a</span><span class="mord mathit">s</span><span class="mord mathit">i</span><span class="mord mathit">c</span><span class="mord mathrm" style="margin-right:0.02778em;">_</span><span class="mord mathit">o</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mord mathit" style="margin-right:0.02778em;">r</span><span class="mord mathit">e</span><span class="mord mathit">a</span><span class="mord mathit">m</span><span class="mord mathrm">@</span><span class="mord mathit" style="margin-right:0.02778em;">D</span><span class="mord mathit" style="margin-right:0.10903em;">U</span><span class="mclose">?</span></span></span></span>char_traits@D@std@@@std@@AAV12@ABV?$MyClass@H@0@@Z) referenced in function _main</p>
</blockquote>
<p>???</p>
<p>es wird offensichtlich im falschen namespace gesucht (&quot;ns::operator&lt;&lt;&quot;), aber dort gehört der operator ja auch nicht hin. wenn ich die funktionsdefinition in den namespace reinkopiere gehts genauso wenig.</p>
<p>thx,<br />
iko.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865030</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865030</guid><dc:creator><![CDATA[iko79]]></dc:creator><pubDate>Sat, 06 Mar 2010 10:43:32 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Fri, 05 Mar 2010 23:38:29 GMT]]></title><description><![CDATA[<p>So geht es bei mir:</p>
<pre><code class="language-cpp">namespace ns
{
    template &lt;class T&gt;
    class MyClass
    {
    private:
        T value;

    public:
        MyClass( T i ) : value( i )        {}

		template &lt;class U&gt;
		friend std::ostream &amp;operator &lt;&lt; ( std::ostream &amp;ostr, const MyClass&lt;U&gt; &amp;mc );
    };

	template &lt;class U&gt;
	std::ostream &amp;operator &lt;&lt; ( std::ostream &amp;ostr, const MyClass&lt;U&gt; &amp;mc )
	{
		ostr &lt;&lt; mc.value;
		return ostr;
	}
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1865031</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865031</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Fri, 05 Mar 2010 23:38:29 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Fri, 05 Mar 2010 23:42:26 GMT]]></title><description><![CDATA[<p>hm. okay...</p>
<p>danke! <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/1865033</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865033</guid><dc:creator><![CDATA[iko79]]></dc:creator><pubDate>Fri, 05 Mar 2010 23:42:26 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 01:01:01 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>So geht es bei mir:</p>
</blockquote>
<p>Ist aber nicht das Gleiche! Jetzt ist jede Templateklasse Freund aller anderen <code>operator&lt;&lt;</code> Templatefunktionen. Dabei sollte die Templateklasse nur Freund der Templatefunktion mit dem gleichen Parameter sein.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/14118">@iko79</a>,<br />
Zuerst eine Korrektur, dann etwas Theorie und am Ende die Lösung <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>iko79 schrieb:</p>
<blockquote>
<p>MSVC 9.0 schrieb:</p>
<blockquote>
<p>1&gt;main.obj : error LNK2019: unresolved external symbol &quot;class std::basic_ostream&lt;char,struct std::char_traits&lt;char&gt; &gt; &amp; __cdecl ns::operator&lt;&lt;(class std::basic_ostream&lt;char,struct std::char_traits&lt;char&gt; &gt; &amp;,class ns::MyClass&lt;int&gt; const &amp;)&quot; (??6ns@@YAAAV?<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>b</mi><mi>a</mi><mi>s</mi><mi>i</mi><mi>c</mi><mi mathvariant="normal">_</mi><mi>o</mi><mi>s</mi><mi>t</mi><mi>r</mi><mi>e</mi><mi>a</mi><mi>m</mi><mi mathvariant="normal">@</mi><mi>D</mi><mi>U</mi><mo>?</mo></mrow><annotation encoding="application/x-tex">basic\_ostream@DU?</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:1.00444em;vertical-align:-0.31em;"></span><span class="base textstyle uncramped"><span class="mord mathit">b</span><span class="mord mathit">a</span><span class="mord mathit">s</span><span class="mord mathit">i</span><span class="mord mathit">c</span><span class="mord mathrm" style="margin-right:0.02778em;">_</span><span class="mord mathit">o</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mord mathit" style="margin-right:0.02778em;">r</span><span class="mord mathit">e</span><span class="mord mathit">a</span><span class="mord mathit">m</span><span class="mord mathrm">@</span><span class="mord mathit" style="margin-right:0.02778em;">D</span><span class="mord mathit" style="margin-right:0.10903em;">U</span><span class="mclose">?</span></span></span></span>char_traits@D@std@@@std@@AAV12@ABV?$MyClass@H@0@@Z) referenced in function _main</p>
</blockquote>
<p>es wird offensichtlich im falschen namespace gesucht (&quot;ns::operator&lt;&lt;&quot;), ...</p>
</blockquote>
<p>Das was du hier vor dir hast, ist kein Kompilerfehler sondern ein Linkerfehler. Die Definition der Funktion kann nicht gefunden werden. Um genau zu sein, wird der freie <code>operator &lt;&lt;</code> gar nie instanziert. Es existiert somit beim Linken gar kein solcher Operator, bzw. es existiert nur eine Deklaration von diesem in deiner Klasse.</p>
<p>Das mag etwas verwirrend klingen, daher probiere ich es dir mal am Code aufzuzeigen:</p>
<pre><code class="language-cpp">int main( int argc, char **argv )
{
    ns::MyClass&lt;int&gt; mc( 10 );
    // Es wurde zum ersten Mal ns::MyClass&lt;int&gt; verwendet, daher wird hier
    // die Templateklasse mit int instanziert. Dadurch wird auch eine
    // Funktionsdeklaration erstellt, nämlich:
    // std::ostream&amp; operator &lt;&lt;(std::ostream&amp;, ns::MyClass&lt;int&gt; const&amp;);

    std::cout &lt;&lt; mc &lt;&lt; std::endl;
    // Um diese Ausgabe zu machen, wird der beste passende operator &lt;&lt; gesucht.
    // Dank ADL (Argument Dependent Lookup) wird zuerst im Scope der Klasse
    // ns::MyClass&lt;int&gt; gesucht. Und dort findet es dann die Deklaration
    // des operator&lt;&lt;. Diese Deklaration reicht dem Kompiler völlig, er braucht
    // keine Definition, um kompilieren zu können.
}
</code></pre>
<p>Wie du siehst, hat der Kompiler gar nie etwas mit dem Funktionstemplate zu tun gehabt. Dieses Template ist schliesslich in einem anderen Scope und dort wurde gar nie gesucht. Es wurde gar nie eine Definition instanziert, wodurch der Linker am Ende meckert, dass es gar keine Definition gibt.</p>
<p>Um dies zu beheben, musst du dem Kompiler irgendwie mitteilen, dass die Funktion in der Klasse mit einem Funktionstemplate ausserhalb der Klasse zusammenhängt. Damit dies überhaupt möglich ist, musst du die Funktionstemplatedefinition (geht auch nur die Deklaration) vor die Klasse ziehen, sonst wäre diese gar nicht bekannt. Mit dem Scope-Operator gibst du dann noch an, in welchem Scope gesucht werden soll. Am Ende sieht dies dann etwa so aus:</p>
<pre><code class="language-cpp">namespace ns 
{ 
    template &lt;class T&gt; 
    class MyClass ;

    template &lt;class T&gt; 
    std::ostream &amp;operator &lt;&lt; ( std::ostream &amp;ostr, const MyClass&lt;T&gt; &amp;mc ) 
    { 
        ostr &lt;&lt; mc.value; 
        return ostr; 
    } 

    template &lt;class T&gt; 
    class MyClass 
    { 
    private: 
        T value; 

    public: 
        MyClass( T i ) : value( i )        {} 

        friend std::ostream &amp;::ns::operator &lt;&lt; ( std::ostream &amp;ostr, const MyClass&lt;T&gt; &amp;mc ); 
//                           ^^^^^^ Angabe wo die Funktion gefunden werden kann
    }; 
} 

int main( int argc, char **argv ) 
{ 
    ns::MyClass&lt;int&gt; mc( 10 ); 

    std::cout &lt;&lt; mc &lt;&lt; std::endl; 
}
</code></pre>
<p>Aber vorsicht nicht template Funktionen werden bevorzugt. Wobei dieser Fehler eher seltener passieren sollte, also dass man nicht template Funktionen mit der gleichen Signatur hat.</p>
<p>Als Alternative steht dir noch die Möglichkeit zur Verfügung die Funktionstemplatedefinition gleich inline in der Klasse zu machen und auf die externe Funktion zu verzichten. Oder wenn die Funktion über Getter implementiert werden kann, dann mache sie nicht zu einem <code>friend</code> . Das erleichtert die Sache auch noch um einiges.</p>
<p>Ich empfehle wenn möglich <code>friend &amp; templates</code> zu vermeiden. Hat meiner Meinung nach viel zu viele Fallstricke.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865040</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865040</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 06 Mar 2010 01:01:01 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 10:19:49 GMT]]></title><description><![CDATA[<p>Hi Dravere,</p>
<p>danke für die ausführliche antwort!</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>So geht es bei mir:</p>
</blockquote>
<p>Ist aber nicht das Gleiche! Jetzt ist jede Templateklasse Freund aller anderen <code>operator&lt;&lt;</code> Templatefunktionen.</p>
</blockquote>
<p>also ich habe anstelle von U (wie bei TyRoXx) T verwendet, das sollte wieder passen, oder nicht?</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Dabei sollte die Templateklasse nur Freund der Templatefunktion mit dem gleichen Parameter sein.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/14118">@iko79</a>,<br />
Zuerst eine Korrektur, dann etwas Theorie und am Ende die Lösung <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>iko79 schrieb:</p>
<blockquote>
<p>MSVC 9.0 schrieb:</p>
<blockquote>
<p>1&gt;main.obj : error LNK2019: unresolved external symbol &quot;class std::basic_ostream&lt;char,struct std::char_traits&lt;char&gt; &gt; &amp; __cdecl ns::operator&lt;&lt;(class std::basic_ostream&lt;char,struct std::char_traits&lt;char&gt; &gt; &amp;,class ns::MyClass&lt;int&gt; const &amp;)&quot; (??6ns@@YAAAV?<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>b</mi><mi>a</mi><mi>s</mi><mi>i</mi><mi>c</mi><mi mathvariant="normal">_</mi><mi>o</mi><mi>s</mi><mi>t</mi><mi>r</mi><mi>e</mi><mi>a</mi><mi>m</mi><mi mathvariant="normal">@</mi><mi>D</mi><mi>U</mi><mo>?</mo></mrow><annotation encoding="application/x-tex">basic\_ostream@DU?</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:1.00444em;vertical-align:-0.31em;"></span><span class="base textstyle uncramped"><span class="mord mathit">b</span><span class="mord mathit">a</span><span class="mord mathit">s</span><span class="mord mathit">i</span><span class="mord mathit">c</span><span class="mord mathrm" style="margin-right:0.02778em;">_</span><span class="mord mathit">o</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mord mathit" style="margin-right:0.02778em;">r</span><span class="mord mathit">e</span><span class="mord mathit">a</span><span class="mord mathit">m</span><span class="mord mathrm">@</span><span class="mord mathit" style="margin-right:0.02778em;">D</span><span class="mord mathit" style="margin-right:0.10903em;">U</span><span class="mclose">?</span></span></span></span>char_traits@D@std@@@std@@AAV12@ABV?$MyClass@H@0@@Z) referenced in function _main</p>
</blockquote>
<p>es wird offensichtlich im falschen namespace gesucht (&quot;ns::operator&lt;&lt;&quot;), ...</p>
</blockquote>
<p>Das was du hier vor dir hast, ist kein Kompilerfehler sondern ein Linkerfehler. Die Definition der Funktion kann nicht gefunden werden. Um genau zu sein, wird der freie <code>operator &lt;&lt;</code> gar nie instanziert. Es existiert somit beim Linken gar kein solcher Operator, bzw. es existiert nur eine Deklaration von diesem in deiner Klasse.</p>
<p>Das mag etwas verwirrend klingen, daher probiere ich es dir mal am Code aufzuzeigen:</p>
<pre><code class="language-cpp">int main( int argc, char **argv )
{
    ns::MyClass&lt;int&gt; mc( 10 );
    // Es wurde zum ersten Mal ns::MyClass&lt;int&gt; verwendet, daher wird hier
    // die Templateklasse mit int instanziert. Dadurch wird auch eine
    // Funktionsdeklaration erstellt, nämlich:
    // std::ostream&amp; operator &lt;&lt;(std::ostream&amp;, ns::MyClass&lt;int&gt; const&amp;);

    std::cout &lt;&lt; mc &lt;&lt; std::endl;
    // Um diese Ausgabe zu machen, wird der beste passende operator &lt;&lt; gesucht.
    // Dank ADL (Argument Dependent Lookup) wird zuerst im Scope der Klasse
    // ns::MyClass&lt;int&gt; gesucht. Und dort findet es dann die Deklaration
    // des operator&lt;&lt;. Diese Deklaration reicht dem Kompiler völlig, er braucht
    // keine Definition, um kompilieren zu können.
}
</code></pre>
<p>Wie du siehst, hat der Kompiler gar nie etwas mit dem Funktionstemplate zu tun gehabt. Dieses Template ist schliesslich in einem anderen Scope und dort wurde gar nie gesucht. Es wurde gar nie eine Definition instanziert, wodurch der Linker am Ende meckert, dass es gar keine Definition gibt.</p>
<p>Um dies zu beheben, musst du dem Kompiler irgendwie mitteilen, dass die Funktion in der Klasse mit einem Funktionstemplate ausserhalb der Klasse zusammenhängt.</p>
</blockquote>
<p>das ist exakt das, was ich abgekürzt mit &quot;es wird offensichtlich im falschen namespace gesucht&quot; meinte <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="🙂"
    /> jedenfalls war das meine vermutung.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Damit dies überhaupt möglich ist, musst du die Funktionstemplatedefinition (geht auch nur die Deklaration) vor die Klasse ziehen, sonst wäre diese gar nicht bekannt. Mit dem Scope-Operator gibst du dann noch an, in welchem Scope gesucht werden soll. Am Ende sieht dies dann etwa so aus:</p>
<pre><code class="language-cpp">namespace ns 
{ 
    template &lt;class T&gt; 
    class MyClass ;

    template &lt;class T&gt; 
    std::ostream &amp;operator &lt;&lt; ( std::ostream &amp;ostr, const MyClass&lt;T&gt; &amp;mc ) 
    { 
        ostr &lt;&lt; mc.value; 
        return ostr; 
    } 

    template &lt;class T&gt; 
    class MyClass 
    { 
    private: 
        T value; 

    public: 
        MyClass( T i ) : value( i )        {} 

        friend std::ostream &amp;::ns::operator &lt;&lt; ( std::ostream &amp;ostr, const MyClass&lt;T&gt; &amp;mc ); 
//                           ^^^^^^ Angabe wo die Funktion gefunden werden kann
    }; 
} 

int main( int argc, char **argv ) 
{ 
    ns::MyClass&lt;int&gt; mc( 10 ); 

    std::cout &lt;&lt; mc &lt;&lt; std::endl; 
}
</code></pre>
</blockquote>
<p>leuchtet ein.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Oder wenn die Funktion über Getter implementiert werden kann, dann mache sie nicht zu einem <code>friend</code> . Das erleichtert die Sache auch noch um einiges.</p>
</blockquote>
<p>also das mit den gettern verstehe ich jetzt nicht. ich soll einen operator als getter implementieren? wie würde sowas aussehen? oder hab ich das jetzt falsch verstanden? ich hab grad GAR keine ahnung, was du meinst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865073</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865073</guid><dc:creator><![CDATA[iko79]]></dc:creator><pubDate>Sat, 06 Mar 2010 10:19:49 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 10:27:51 GMT]]></title><description><![CDATA[<p>iko79 schrieb:</p>
<blockquote>
<p>also das mit den gettern verstehe ich jetzt nicht. ich soll einen operator als getter implementieren? wie würde sowas aussehen? oder hab ich das jetzt falsch verstanden? ich hab grad GAR keine ahnung, was du meinst.</p>
</blockquote>
<p>Er meint, du sollst nicht direkt auf die privaten Daten zugreifen, sondern Get-Funktionen einrichten.</p>
<pre><code class="language-cpp">template &lt;typename T&gt; 
class MyClass 
{ 
    private: 
        T value; 

    public: 
        T GetValue() const
        {
             return value;
        }
    // ...
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1865076</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865076</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 06 Mar 2010 10:27:51 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 10:30:30 GMT]]></title><description><![CDATA[<p>iko79 schrieb:</p>
<blockquote>
<p>also das mit den gettern verstehe ich jetzt nicht. ich soll einen operator als getter implementieren? wie würde sowas aussehen? oder hab ich das jetzt falsch verstanden? ich hab grad GAR keine ahnung, was du meinst.</p>
</blockquote>
<p>Ich denk mal er meint du sllst einen Getter implementieren für die Elemente, die beim op&lt;&lt; ausgegeben werden sollen, um dir die friend-Deklaratoin sparen zu können. Davon würd ich aber abraten, da du damit diese Member nicht nur dem op&lt;&lt; sondern allen Benutzern der Klasse offenlegst. Um die friend-Deklaration zu vermeiden kann man eher folgendes machen:</p>
<pre><code class="language-cpp">namespace ns
{

template &lt;class T&gt;
class Foo
{
  int value;
public:
  ostream&amp; print(ostream&amp; os) const
  {
    os &lt;&lt; value;
    return os;
  }
};
template &lt;class T&gt;
inline ostream&amp; operator&lt;&lt; (ostream&amp; os, Foo&lt;T&gt;const&amp; f)
{
  return f.print(os);
}

}//end namespace ns
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1865077</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865077</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sat, 06 Mar 2010 10:30:30 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 10:43:17 GMT]]></title><description><![CDATA[<p>achsooo, allesklar. <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="🙂"
    /> besten dank an euch drei!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865080</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865080</guid><dc:creator><![CDATA[iko79]]></dc:creator><pubDate>Sat, 06 Mar 2010 10:43:17 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 11:08:03 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Davon würd ich aber abraten, da du damit diese Member nicht nur dem op&lt;&lt; sondern allen Benutzern der Klasse offenlegst.</p>
</blockquote>
<p>Das hängt davon ab, ob <code>value</code> nur ein Implementierungsdetail oder eine tatsächliche Eigenschaft der Klasse repräsentiert, auf welche man auch sonst Zugriff haben darf. Da der Member immerhin ausgegeben werden soll, liegt es von mir aus gesehen nahe, dass es sich eben um kein Implementierungsdetail handelt.</p>
<p>Die Frage ist auch, ob eine <code>print()</code> -Funktion viel besser ist, wenn sie lediglich als Indirektion des <code>operator&lt;&lt;</code> benutzt wird. Nur um kein <code>friend</code> zu haben, ich weiss ja nicht...<br />
Eine Alternative wäre auch sowas wie <code>std::string ToString() const</code> , was sich aber auch erst wirklich auszahlt, wenn man die Stringrepräsentation auch noch an anderen Orten benötigt. Ansonsten scheint mir der <code>friend operator&lt;&lt;</code> gar nicht mal so abwegig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865087</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865087</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 06 Mar 2010 11:08:03 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 11:15:52 GMT]]></title><description><![CDATA[<p>iko79 schrieb:</p>
<blockquote>
<p>also ich habe anstelle von U (wie bei TyRoXx) T verwendet, das sollte wieder passen, oder nicht?</p>
</blockquote>
<p>Es darf aber über der friend Deklaration auch kein <code>template&lt;typename T&gt;</code> haben. Einfach nur so, wie ich es gezeigt habe.</p>
<p>iko79 schrieb:</p>
<blockquote>
<p>das ist exakt das, was ich abgekürzt mit &quot;es wird offensichtlich im falschen namespace gesucht&quot; meinte <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="🙂"
    /> jedenfalls war das meine vermutung.</p>
</blockquote>
<p>Da ist aber ein wenig sehr heftig abgekürzt. Ich hoffe aber mal, dass du den Unterschied verstanden hast zwischen Linker und Kompiler in diesem Fall. Es sind verdammt viele verschiedene Konzepte hier im Einsatz, damit dieser Fehler entsteht.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Ich denk mal er meint du sllst einen Getter implementieren für die Elemente, die beim op&lt;&lt; ausgegeben werden sollen, um dir die friend-Deklaratoin sparen zu können.</p>
</blockquote>
<p>Nicht ganz, ich meinte nur, falls es bereits Getter hat, dass man diese verwenden soll. Ich habe schon viele gesehen, welche eine freie Funktion als <code>friend</code> deklarierten, obwohl sie diese auch einfach mit den bereits vorhandenen Gettern der Klasse schreiben hätten können.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/12954">@Nexus</a>,<br />
Die Printfunktion hat einen kleinen netten Vorteil. Man kann sie <code>virtual</code> machen.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865090</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 06 Mar 2010 11:15:52 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 14:31:02 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Die Frage ist auch, ob eine <code>print()</code> -Funktion viel besser ist, wenn sie lediglich als Indirektion des <code>operator&lt;&lt;</code> benutzt wird. Nur um kein <code>friend</code> zu haben, ich weiss ja nicht...</p>
</blockquote>
<p>Siehs andersrum: Die print-Methode ist Teil des Klasseninterfaces und braucht Zugriff auf private Elemente, muss also selbst Methode der Klasse sein.<br />
Der op&lt;&lt; ist nur der Bonus dazu, der die gewohnte Ausgabe und das Chaining möglich macht. Die friend-Deklaration ist imo eine Unart. Statt erst das Paket ordentlich zu schnüren (ein ordentliches Interface wo alles was Methode sein muss auch Methode ist und alles was freie Funktion sein kann auch freie Funktion ist), und dann die Schleife (den schöner lesbaren op&lt;&lt;) drumzumachen, wird das Paket und seine Kapselung mit dem friend-Brecheisen aufgehebelt um die Schleife dranzubäppen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865140</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865140</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sat, 06 Mar 2010 14:31:02 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 15:04:17 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>iko79 schrieb:</p>
<blockquote>
<p>also ich habe anstelle von U (wie bei TyRoXx) T verwendet, das sollte wieder passen, oder nicht?</p>
</blockquote>
<p>Es darf aber über der friend Deklaration auch kein <code>template&lt;typename T&gt;</code> haben. Einfach nur so, wie ich es gezeigt habe.</p>
</blockquote>
<p>achja.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>iko79 schrieb:</p>
<blockquote>
<p>das ist exakt das, was ich abgekürzt mit &quot;es wird offensichtlich im falschen namespace gesucht&quot; meinte <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="🙂"
    /> jedenfalls war das meine vermutung.</p>
</blockquote>
<p>Da ist aber ein wenig sehr heftig abgekürzt. Ich hoffe aber mal, dass du den Unterschied verstanden hast zwischen Linker und Kompiler in diesem Fall. Es sind verdammt viele verschiedene Konzepte hier im Einsatz, damit dieser Fehler entsteht.</p>
</blockquote>
<p>ich habe die erfahrung gemacht, dass fragen umso weniger beantwortet werden, umso ausführlicher man sie formuliert. vermutlich clicken viele einfach gleich weiter wenn sie 'nen langen text sehen. darum beschränke ich mich seit einiger zeit auf das absolut notwendigste wenn ich 'ne frage poste. auch wenn ich mich mit template-syntax immer wieder verheddere -- ich bin absolut kein anfänger und weiß sehr wohl was compiler und linker sind <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="😉"
    /> long story short -- ja, ich habs verstanden und genau genommen ists genau der fehler, den ich vermutet habe, ich wusste nur nicht, wie ich ihn beseitigen soll.</p>
<p>iko79 schrieb:</p>
<blockquote>
<p>achsooo, allesklar. <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="🙂"
    /> besten dank an euch drei!</p>
</blockquote>
<p>an euch vier, sorry! hab den ersten post von Nexus ganz übersehen....</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865147</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865147</guid><dc:creator><![CDATA[iko79]]></dc:creator><pubDate>Sat, 06 Mar 2010 15:04:17 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 15:25:58 GMT]]></title><description><![CDATA[<p>iko79 schrieb:</p>
<blockquote>
<p>auch wenn ich mich mit template-syntax immer wieder verheddere -- ich bin absolut kein anfänger und weiß sehr wohl was compiler und linker sind <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>Dann empfehle ich dir &quot;C++ Templates - the Complete Guide&quot; von Josuttis/Vandervoorde. Die gehn auf alle Details ein, auch Compilertechnisch gesehen, dass man ein ziemlich guted Verständnis von dem bekommen kann, was da passiert und entsprechend auch schnell weiß was hinter einer Fehlermeldung steckt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865156</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865156</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sat, 06 Mar 2010 15:25:58 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sat, 06 Mar 2010 17:10:46 GMT]]></title><description><![CDATA[<p>iko79 schrieb:</p>
<blockquote>
<p>ich habe die erfahrung gemacht, dass fragen umso weniger beantwortet werden, umso ausführlicher man sie formuliert. vermutlich clicken viele einfach gleich weiter wenn sie 'nen langen text sehen. darum beschränke ich mich seit einiger zeit auf das absolut notwendigste wenn ich 'ne frage poste.</p>
</blockquote>
<p>Das ist grundsätzlich schon richtig, nur sollte die Problemstellung trotzdem korrekt und vollständig sein. Ich klicke oft auch Beiträge weg, wo es mich einfach nur nervt, weil wieder die Hälfte fehlt oder man denjenigen zuerst über den Fehler aufklären muss, was er wirklich bedeutet <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>iko79 schrieb:</p>
<blockquote>
<p>ja, ich habs verstanden und genau genommen ists genau der fehler, den ich vermutet habe, ich wusste nur nicht, wie ich ihn beseitigen soll.</p>
</blockquote>
<p>Dann ist ja gut, wollte nur sicher gehen.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Dann empfehle ich dir &quot;C++ Templates - the Complete Guide&quot; von Josuttis/Vandervoorde.</p>
</blockquote>
<p>Kann ich nur unterstreichen:<br />
<a href="https://duckduckgo.com/?q=isbn+9780201734843&amp;cppnetbooks" rel="nofollow">C++ Templates | ISBN: 9780201734843</a></p>
<p>Habe auch in diesem Fall schnell in dem Buch nachgeschlagen, um sicher zu sein, dass ich keinen Mist erzähle <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>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865200</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865200</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 06 Mar 2010 17:10:46 GMT</pubDate></item><item><title><![CDATA[Reply to [solved] wieder mal: templates vs. iostream on Sun, 07 Mar 2010 10:51:27 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Siehs andersrum: Die print-Methode ist Teil des Klasseninterfaces und braucht Zugriff auf private Elemente, muss also selbst Methode der Klasse sein.</p>
</blockquote>
<p>Ja, von der Kapselung her gesehen ist eine Memberfunktion tatsächlich schöner. Zumindest auf den ersten Blick...</p>
<p>Ich meinte eher, dass dadurch nicht nur Vorteile entstehen. Zum einen ist das Interface grösser (soll ich <code>obj.print(stream)</code> oder <code>stream &lt;&lt; obj</code> schreiben?), zum anderen kann es oft sein, dass gar kein Zugriff auf private Member notwendig ist, weil ausreichend Getter bereitstehen. Soll man in diesen Fällen auch eine <code>print()</code> -Memberfunktion einrichten? Damit würde man die Kapselung unnötigerweise verringern. Andererseits ist es inkonsistent und für den Benutzer verwirrend, wenn ein paar Klassen <code>operator&lt;&lt;</code> und <code>print()</code> , ein paar andere hingegen nur <code>operator&lt;&lt;</code> unterstützen. Dazu kommt, dass <code>operator&lt;&lt;</code> als Stream-Operator den gängigen Konventionen entspricht, die jeder C++-Programmierer kennt. Bei <code>print()</code> muss man sich genau in Dokumentationen einlesen, weil es jeder etwas anders macht (bzw. gar nicht, wie die Standardbibliothek).</p>
<p>Meiner Meinung nach ist <code>friend</code> legitim, wenn es im Endeffekt die Kapselung vergrössert, indem es andere Funktionen unnötig macht. Ob das hier der Fall ist, darüber kann man streiten...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1865385</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1865385</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 07 Mar 2010 10:51:27 GMT</pubDate></item></channel></rss>