<?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[friend Operator Linkerfehler]]></title><description><![CDATA[<p>Hi,</p>
<p>warum erzeugt dieser Code einen Linkerfehler?</p>
<pre><code>template&lt;typename Val&gt;
class Size
{
public:
	friend bool operator==(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs);
};

template&lt;typename Val&gt;
bool operator==(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs)
{
	return true;
}

typedef Size&lt;float&gt; SizeF;

int main()
{
	SizeF s, s2;
	bool x = s == s2;
}
</code></pre>
<p>Der GCC hat dann als Hinweis ausgegeben, dass es mit</p>
<pre><code>friend bool operator==&lt;&gt;(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs)
</code></pre>
<p>geht. Warum sind hier die &lt;&gt; erforderlich?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/320721/friend-operator-linkerfehler</link><generator>RSS for Node</generator><lastBuildDate>Thu, 23 Jul 2026 18:37:48 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/320721.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 09 Oct 2013 11:02:08 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to friend Operator Linkerfehler on Wed, 09 Oct 2013 11:02:08 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>warum erzeugt dieser Code einen Linkerfehler?</p>
<pre><code>template&lt;typename Val&gt;
class Size
{
public:
	friend bool operator==(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs);
};

template&lt;typename Val&gt;
bool operator==(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs)
{
	return true;
}

typedef Size&lt;float&gt; SizeF;

int main()
{
	SizeF s, s2;
	bool x = s == s2;
}
</code></pre>
<p>Der GCC hat dann als Hinweis ausgegeben, dass es mit</p>
<pre><code>friend bool operator==&lt;&gt;(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs)
</code></pre>
<p>geht. Warum sind hier die &lt;&gt; erforderlich?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359094</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359094</guid><dc:creator><![CDATA[KN4CK3R]]></dc:creator><pubDate>Wed, 09 Oct 2013 11:02:08 GMT</pubDate></item><item><title><![CDATA[Reply to friend Operator Linkerfehler on Wed, 09 Oct 2013 11:03:53 GMT]]></title><description><![CDATA[<p>Weil es sonst nicht als Template Funktion erkannt wird</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359096</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359096</guid><dc:creator><![CDATA[kralo9]]></dc:creator><pubDate>Wed, 09 Oct 2013 11:03:53 GMT</pubDate></item><item><title><![CDATA[Reply to friend Operator Linkerfehler on Wed, 09 Oct 2013 11:29:28 GMT]]></title><description><![CDATA[<p>so ungefähr müßte es eigentlich gehen:</p>
<pre><code>template&lt;typename Val&gt;
class Size
{
public:
    template&lt;typename Val_&gt;
    friend bool operator==(const Size&lt;Val_&gt; &amp;lhs, const Size&lt;Val_&gt; &amp;rhs);
};

template&lt;typename Val&gt;
bool operator==(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs)
{
    return true;
}

typedef Size&lt;float&gt; SizeF;

int main()
{
    SizeF s, s2;
    bool x = s == s2;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2359103</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359103</guid><dc:creator><![CDATA[dd++ 0]]></dc:creator><pubDate>Wed, 09 Oct 2013 11:29:28 GMT</pubDate></item><item><title><![CDATA[Reply to friend Operator Linkerfehler on Wed, 09 Oct 2013 11:58:37 GMT]]></title><description><![CDATA[<blockquote>
<p>warum erzeugt dieser Code einen Linkerfehler?</p>
</blockquote>
<p>Weil du in der Klasse eine <em>Funktion</em> deklarierst, die natürlich nicht definiert ist. Nur das Funktions<em>template</em> außerhalb. Name Lookup findet aber deine Funktion zuerst. Und das führt zum Linkerfehler.</p>
<p>Kralo hat Recht:</p>
<p>§14.5.4 schrieb:</p>
<blockquote>
<p>For a friend function declaration that is not a template declaration:<br />
— if the name of the friend is a qualified or unqualified template-id, the friend declaration refers to a specialization of a function template, otherwise<br />
[...]<br />
— the name shall be an unqualified-id that declares (or redeclares) an ordinary (non-template) function.</p>
</blockquote>
<p>Entweder du gibst eine template-id an, oder die Funktion die du deklarierst darf auf kein Funktionstemplate verweisen.</p>
<p>Nun ist aber das Problem, dass die template-id nicht auf eine nicht deklarierte Funktion verweisen darf - denn sie deklariert selbst nichts. Lösung:</p>
<pre><code>template&lt;typename&gt; class Size; // Vorwärtsdeklaration
template&lt;typename Val&gt; bool operator==(Size&lt;Val&gt; const&amp; lhs, Size&lt;Val&gt; const&amp; rhs);

template&lt;typename Val&gt;
class Size
{
public:
    // Damit wird jede Spezialisierung Size&lt;Val&gt; genau den Freund operator==&lt;Val&gt; haben
    friend bool operator==&lt;Val&gt;(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs);
};

template&lt;typename Val&gt;
bool operator==(const Size&lt;Val&gt; &amp;lhs, const Size&lt;Val&gt; &amp;rhs)
{
    return true;
}

int main()
{
    Size&lt;float&gt; s, s2;
    s == s2;
}
</code></pre>
<p>Jedoch ist die Methode von dd++ natürlich ein wenig kürzer. Dafür ist die Kapselung stärker gebrochen(!).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359112</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Wed, 09 Oct 2013 11:58:37 GMT</pubDate></item><item><title><![CDATA[Reply to friend Operator Linkerfehler on Wed, 09 Oct 2013 11:59:33 GMT]]></title><description><![CDATA[<p>Ja, die &lt;&gt; bzw jetzt &lt;Val&gt; Version gefällt mir auch besser. Danke für eure Hilfe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359113</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359113</guid><dc:creator><![CDATA[KN4CK3R]]></dc:creator><pubDate>Wed, 09 Oct 2013 11:59:33 GMT</pubDate></item><item><title><![CDATA[Reply to friend Operator Linkerfehler on Wed, 09 Oct 2013 12:14:58 GMT]]></title><description><![CDATA[<p>KN4CK3R schrieb:</p>
<blockquote>
<p>Ja, die &lt;&gt; bzw jetzt &lt;Val&gt; Version gefällt mir auch besser. Danke für eure Hilfe.</p>
</blockquote>
<p>Du kannst auch &lt;&gt; verwenden. Dann werden die Template-Argumente automatisch deduziert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359122</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359122</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Wed, 09 Oct 2013 12:14:58 GMT</pubDate></item><item><title><![CDATA[Reply to friend Operator Linkerfehler on Wed, 09 Oct 2013 12:28:32 GMT]]></title><description><![CDATA[<p>Ich versteh genau Bahnhof. Was macht &lt;T&gt; besser als &lt;&gt;? Beispiel bitte.<br />
Bisher wusste ich gar nicht, dass &lt;T&gt; an der Stelle ueberhaupt erlaubt ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359127</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 09 Oct 2013 12:28:32 GMT</pubDate></item></channel></rss>