<?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-friends: Bug in compiler]]></title><description><![CDATA[<p>Hallo</p>
<p>VC8 akzeptiert folgenden Code, gcc 4.3 nicht. Wieso?</p>
<pre><code class="language-cpp">template&lt;class A&gt; void foo2(A)
{
}
template&lt;class A,template&lt;class&gt;class B&gt; void foo(B&lt;A&gt;)
{
}
template&lt;class&gt; class bar
{
	template&lt;class A,template&lt;class&gt;class B&gt; friend void foo(B&lt;A&gt;);
	template&lt;class A&gt; friend void foo2(A);
};

int main(int num_arguments, char* arguments[])
{
	foo2(bar&lt;int&gt;());//OK
	foo(bar&lt;int&gt;());/*main.cpp:308: error: call of overloaded 'foo(bar&lt;int&gt;)' is ambiguous
main.cpp:298: note: candidates are: void foo(B&lt;A&gt;) [with A = int, B = bar]
main.cpp:303: note:                 void foo(B&lt;A&gt;) [with A = int, B = bar, &lt;template-parameter-1-1&gt; = int]*/
}
</code></pre>
<p>::oo(bar&lt;int&gt;()) funktioniert zwar, aber diese Funktion ist kein friend von der bar-Klasse. Anscheinend gibt es also zwei verschiedene foo-Deklarationen.</p>
<p>Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/235275/template-friends-bug-in-compiler</link><generator>RSS for Node</generator><lastBuildDate>Thu, 24 Sep 2026 06:23:11 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/235275.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 27 Feb 2009 19:24:17 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to template-friends: Bug in compiler on Fri, 27 Feb 2009 19:24:17 GMT]]></title><description><![CDATA[<p>Hallo</p>
<p>VC8 akzeptiert folgenden Code, gcc 4.3 nicht. Wieso?</p>
<pre><code class="language-cpp">template&lt;class A&gt; void foo2(A)
{
}
template&lt;class A,template&lt;class&gt;class B&gt; void foo(B&lt;A&gt;)
{
}
template&lt;class&gt; class bar
{
	template&lt;class A,template&lt;class&gt;class B&gt; friend void foo(B&lt;A&gt;);
	template&lt;class A&gt; friend void foo2(A);
};

int main(int num_arguments, char* arguments[])
{
	foo2(bar&lt;int&gt;());//OK
	foo(bar&lt;int&gt;());/*main.cpp:308: error: call of overloaded 'foo(bar&lt;int&gt;)' is ambiguous
main.cpp:298: note: candidates are: void foo(B&lt;A&gt;) [with A = int, B = bar]
main.cpp:303: note:                 void foo(B&lt;A&gt;) [with A = int, B = bar, &lt;template-parameter-1-1&gt; = int]*/
}
</code></pre>
<p>::oo(bar&lt;int&gt;()) funktioniert zwar, aber diese Funktion ist kein friend von der bar-Klasse. Anscheinend gibt es also zwei verschiedene foo-Deklarationen.</p>
<p>Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1671585</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1671585</guid><dc:creator><![CDATA[BlubDerBlubber]]></dc:creator><pubDate>Fri, 27 Feb 2009 19:24:17 GMT</pubDate></item><item><title><![CDATA[Reply to template-friends: Bug in compiler on Sat, 28 Feb 2009 13:31:27 GMT]]></title><description><![CDATA[<p>Ich pushe mal. Falls bis heute abend keiner eine Idee hat, werde ich mal ein testcase vorbereiten und an den gcc bugtracker schicken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1671967</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1671967</guid><dc:creator><![CDATA[BlubDerBlubber]]></dc:creator><pubDate>Sat, 28 Feb 2009 13:31:27 GMT</pubDate></item><item><title><![CDATA[Reply to template-friends: Bug in compiler on Sat, 28 Feb 2009 14:11:41 GMT]]></title><description><![CDATA[<p>Das ist meiner Meinung nach kein Fehler, sondern ist Teil des sehr komplizierten Standards für Friend-Function-Templates. In deiner Klasse <code>bar</code> wird tatsächlich eine neue Funktion <code>foo</code> erzeugt, allerdings nur eine neue Deklaration ohne Definition. Um dies zu verhindern, muss du die Funktion explizit angeben:</p>
<pre><code class="language-cpp">template&lt;typename T1, template&lt;class&gt; class T2&gt;
void foo(T2&lt;T1&gt;)
{
}

template&lt;typename&gt;
class Bar
{
  template&lt;typename T1, template&lt;class&gt; class T2&gt;
  friend void ::foo(T2&lt;T1&gt;);

  //          ^^
  //          ||
  // Dieser Scope-Operator ist entscheidend.
}
</code></pre>
<p>Wieso es bei deinem <code>foo2</code> funktioniert, bin ich mir nicht ganz sicher. Aber es könnte womöglich an ADL (Argument Dependent Lookup) liegen, dass es nämlich die zweite Deklaration von <code>foo2</code> in <code>bar</code> bevorzugt. Würde aber bedeuten, dass es beim Linken zu einem Fehler geführt hätte, da es keine Definition gibt. Allerdings rate ich hier jetzt eher, als das ich es mit Sicherheit weiss. Vielleicht kann noch jemand anderes etwas dazu beisteuern.</p>
<p>Edit: Fehlerkorrektur und noch etwas zusätzliches<br />
Buchempfehlung:<br />
C++ Templates - The Complete Guide<br />
von<br />
David Vandevoorde &amp; Nicolai M. Josuttis</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1671978</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1671978</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 28 Feb 2009 14:11:41 GMT</pubDate></item><item><title><![CDATA[Reply to template-friends: Bug in compiler on Sat, 28 Feb 2009 14:16:14 GMT]]></title><description><![CDATA[<p>zwei vorgestellte Doppelpunkte in der Friend-Deklaration habe ich schon probiert - das hat nichts gebracht.</p>
<p>[quote=Dravere ]In deiner Klasse bar wird tatsächlich eine neue Funktion foo erzeugt, allerdings nur eine neue Deklaration ohne Definition. Um dies zu verhindern, muss du die Funktion explizit angeben: [/quote]<br />
Es ist so oder so eine Deklaration - dadurch dass ich die Signatur mit einem ; endenen lasse statt mit einer Definition (z.B. durch { und } ). Das :: ist dann nur ein expliziter Scope-bezeichner, wobei der überflüssig ist, da ja implizit der aktuelle scope (in meinem Fall global namespace) genutzt wird.</p>
<p>Das Problem ist in meinen Augen, dass das Frontend eine Abhängigkeit zu dem Klassen-Templateparameter einfügt (wieso auch immer?), und demnach gibt es zwei Deklarationen (zeigt ja auch die Fehlermeldung). Afaik ist dies falsch?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1671980</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1671980</guid><dc:creator><![CDATA[BlubDerBlubber]]></dc:creator><pubDate>Sat, 28 Feb 2009 14:16:14 GMT</pubDate></item><item><title><![CDATA[Reply to template-friends: Bug in compiler on Sat, 28 Feb 2009 14:17:41 GMT]]></title><description><![CDATA[<p>BlubDerBlubber schrieb:</p>
<blockquote>
<p>Dravere schrieb:</p>
<blockquote>
<p>In deiner Klasse bar wird tatsächlich eine neue Funktion foo erzeugt, allerdings nur eine neue Deklaration ohne Definition. Um dies zu verhindern, muss du die Funktion explizit angeben:</p>
</blockquote>
<p>Es ist so oder so eine Deklaration - dadurch dass ich die Signatur mit einem ; endenen lasse statt mit einer Definition (z.B. durch { und } ). Das :: ist dann nur ein expliziter Scope-bezeichner, wobei der überflüssig ist, da ja implizit der aktuelle scope (in meinem Fall global namespace) genutzt wird.</p>
</blockquote>
<p>Ähh, sorry, habe dich falsch verstanden. Ignorier den ersten Satz <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/1671983</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1671983</guid><dc:creator><![CDATA[BlubDerBlubber]]></dc:creator><pubDate>Sat, 28 Feb 2009 14:17:41 GMT</pubDate></item><item><title><![CDATA[Reply to template-friends: Bug in compiler on Sat, 28 Feb 2009 14:31:59 GMT]]></title><description><![CDATA[<p>Ich habe leider keinen g++ hier und der MSVC ist viel zu nett mit dem Programmierer und vereinfacht diese verteufelte friend Deklaration, daher kann ich grad schlecht testen. Aber ich bin nochmal über das Buch gegangen. Eine Möglichkeit wäre noch das Folgende:</p>
<pre><code class="language-cpp">template&lt;typename T1, template&lt;class&gt; class T2&gt;
void foo(T2&lt;T1&gt;)
{ 
}

template&lt;typename&gt;
class Bar
{
  template&lt;typename T1, template&lt;class&gt; class T2&gt;
  friend void foo&lt;T1, T2&gt;(T2&lt;T1&gt;);
}
</code></pre>
<p>Oder dies:</p>
<pre><code class="language-cpp">template&lt;typename T1, template&lt;class&gt; class T2&gt;
friend void foo&lt;&gt;(T2&lt;T1&gt;);
</code></pre>
<p>Oder eine der beiden mit entsprechendem Scope-Operator davor <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="🙂"
    /><br />
Einfach mal ausprobieren <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>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1671988</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1671988</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 28 Feb 2009 14:31:59 GMT</pubDate></item><item><title><![CDATA[Reply to template-friends: Bug in compiler on Sat, 28 Feb 2009 14:39:27 GMT]]></title><description><![CDATA[<p>hehe - alles schon ausprobiert <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>
<pre><code class="language-cpp">template&lt;class A,template&lt;class&gt;class B&gt; void foo(B&lt;A&gt;)
{
}
template&lt;class&gt; class bar
{
	template&lt;class A,template&lt;class&gt;class B&gt; friend void foo&lt;&gt;(B&lt;A&gt;);//error: invalid use of template-id 'foo&lt;&gt;' in declaration of primary template
	template&lt;class A,template&lt;class&gt;class B&gt; friend void ::foo&lt;&gt;(B&lt;A&gt;);//error: invalid use of template-id 'foo&lt;&gt;' in declaration of primary template
	template&lt;class A,template&lt;class&gt;class B&gt; friend void foo&lt;A,B&gt;(B&lt;A&gt;);//error: invalid use of template-id 'foo&lt;A, template&lt;class&gt; template&lt;class&gt; class B&gt;' in declaration of primary template
	template&lt;class A,template&lt;class&gt;class B&gt; friend void ::foo&lt;A,B&gt;(B&lt;A&gt;);//error: invalid use of template-id 'foo&lt;A, template&lt;class&gt; template&lt;class&gt; class B&gt;' in declaration of primary template
};

int main(int num_arguments, char* arguments[])
{
    foo(bar&lt;int&gt;());
}
</code></pre>
<p>btw.: gcc 4.3.3 für Windows:</p>
<pre><code class="language-cpp">http://www.tdragon.net/recentgcc
</code></pre>
<p>Läuft bei mir seit monaten tadellos, selbst in produktiven Umgebungen!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1671990</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1671990</guid><dc:creator><![CDATA[BlubDerBlubber]]></dc:creator><pubDate>Sat, 28 Feb 2009 14:39:27 GMT</pubDate></item><item><title><![CDATA[Reply to template-friends: Bug in compiler on Sat, 28 Feb 2009 23:50:12 GMT]]></title><description><![CDATA[<p>Mal schaun, was draus wird.<br />
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39328" rel="nofollow">http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39328</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1672221</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1672221</guid><dc:creator><![CDATA[BlubDerBlubber]]></dc:creator><pubDate>Sat, 28 Feb 2009 23:50:12 GMT</pubDate></item></channel></rss>