<?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[Partial ordering of function templates and default arguments]]></title><description><![CDATA[<p>Ist das zweite Funktionstemplate unten &quot;more specialized&quot; (C++ Standard, 14.5.5.2 Partial ordering of function templates) als das erste?:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;, T* = 0) {}

template &lt;typename T&gt;
void f(T const&amp;, T** = 0) {}
</code></pre>
<p>Wenn ja, warum wird folgendes Programm nicht kompiliert?:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;, T* = 0) {}

template &lt;typename T&gt;
void f(T const&amp;, T** = 0) {}

int main()
{
	int i;
	f(i); // VC++ 8.0 - 'f' : ambiguous call to overloaded function
	      // Comeau C/C++ 4.3.3 - more than one instance of overloaded function &quot;f&quot;
}
</code></pre>
<p>Wenn nein, warum wird folgendes Programm kompiliert?:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;, T* = 0) {}

template &lt;typename T&gt;
void f(T const&amp;, T** = 0) {}

int main()
{
	int i;
	f(i, (int**) 0);
}
</code></pre>
<p>Oder hängt es auch vom Aufruf ab, ob ein Funktionstemplate &quot;more specialized&quot; als ein anderes ist? Aber im C++-Standard steht &quot;A template is more specialized than another ...&quot; und nicht etwa &quot;A template using is more specialized ...&quot;, und das einzige, was indirekt sagt, dass &quot;partitial ordering&quot; von zwei Funktionstemplates von ihrer Verwendung abhängt, ist das Wort &quot;unused&quot; in &quot;The presence of unused ellipsis and default arguments has no effect on the partial ordering of function templates&quot;. Habe ich irgendwas im Standard übersehen?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/145237/partial-ordering-of-function-templates-and-default-arguments</link><generator>RSS for Node</generator><lastBuildDate>Wed, 02 Sep 2026 23:42:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/145237.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 26 Apr 2006 08:54:24 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 08:57:51 GMT]]></title><description><![CDATA[<p>Ist das zweite Funktionstemplate unten &quot;more specialized&quot; (C++ Standard, 14.5.5.2 Partial ordering of function templates) als das erste?:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;, T* = 0) {}

template &lt;typename T&gt;
void f(T const&amp;, T** = 0) {}
</code></pre>
<p>Wenn ja, warum wird folgendes Programm nicht kompiliert?:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;, T* = 0) {}

template &lt;typename T&gt;
void f(T const&amp;, T** = 0) {}

int main()
{
	int i;
	f(i); // VC++ 8.0 - 'f' : ambiguous call to overloaded function
	      // Comeau C/C++ 4.3.3 - more than one instance of overloaded function &quot;f&quot;
}
</code></pre>
<p>Wenn nein, warum wird folgendes Programm kompiliert?:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;, T* = 0) {}

template &lt;typename T&gt;
void f(T const&amp;, T** = 0) {}

int main()
{
	int i;
	f(i, (int**) 0);
}
</code></pre>
<p>Oder hängt es auch vom Aufruf ab, ob ein Funktionstemplate &quot;more specialized&quot; als ein anderes ist? Aber im C++-Standard steht &quot;A template is more specialized than another ...&quot; und nicht etwa &quot;A template using is more specialized ...&quot;, und das einzige, was indirekt sagt, dass &quot;partitial ordering&quot; von zwei Funktionstemplates von ihrer Verwendung abhängt, ist das Wort &quot;unused&quot; in &quot;The presence of unused ellipsis and default arguments has no effect on the partial ordering of function templates&quot;. Habe ich irgendwas im Standard übersehen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1045461</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045461</guid><dc:creator><![CDATA[igna]]></dc:creator><pubDate>Wed, 26 Apr 2006 08:57:51 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 09:01:41 GMT]]></title><description><![CDATA[<p>Ja, das zweite Template ist stärker spezialisiert. Allerdings werden Default-Parameter bei der Auflösung des Ziel-Templates nicht berücksichtigt - und wenn du den zweiten Parameter weglässt, bleibt von beiden Funktionen nur &quot;f(int const&amp;);&quot; übrig.</p>
<p>Aber das steht doch auch in dem Satz, den du dort zitiert hast:</p>
<blockquote>
<p>The presence of unused ellipsis <strong>and default arguments</strong> has no effect on the partial ordering of function templates</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1045471</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045471</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 26 Apr 2006 09:01:41 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 09:10:36 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/12481">@igna</a><br />
die partielle Ordnung wird nur auf die &quot;viable functions&quot; angewendet, also auf die Funktionen, die potentiell aufrufbar sind.<br />
Default-Argumente und Ellipsen werden dabei Ordnung ignoriert. Gedanklich kannst du sie also aus den Parameterlisten rausstreichen.</p>
<p>Gegeben deine zwei Funktionen:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;, T* = 0) {}

template &lt;typename T&gt;
void f(T const&amp;, T** = 0) {}
</code></pre>
<p>Für den Aufruf:</p>
<pre><code class="language-cpp">f(42);
</code></pre>
<p>sind beide Überladungen aufrufbar. Es wird also der Algorithmus für die partielle Ordnung angeworfen. Der kann aber keinen eindeutigen Kandidaten finden, denn nach der Streichung der Default-Parameter hast du:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;) {}

template &lt;typename T&gt;
void f(T const&amp;) {}
</code></pre>
<p>Hier ist natürlich keine Funktion spezialisierter als die andere. Der Aufruf ist mehrdeutig.</p>
<p>Für den Aufruf:</p>
<pre><code class="language-cpp">f(42, (int**)0);
</code></pre>
<p>hingegen gibt es überhaupt nur eine Kandidatenfunktion. Der Grund: für die erste Funktion gibt es keine Ersetzung von T, die zu den Argumenten kompatibel ist. 42 hat den Typ int. Setzt man T = int, ist der zweite Parameter vom Typ int*. Das zweite Argument hat aber den Typ int**, was nicht kompatibel zu int* ist. Andersherum, setzt man T auf int*, dann passt zwar der zweite Parameter, nicht aber der erste.</p>
<p>Da es nur eine Kandidatenfunktion gibt, findet hier gar keine partielle Ordnung statt. In diesem Fall spielt es also überhaupt keine Rolle, welche Funktion spezieller ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1045478</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045478</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Wed, 26 Apr 2006 09:10:36 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 09:21:24 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Ja, das zweite Template ist stärker spezialisiert.</p>
</blockquote>
<p>Findest du nicht, dass das zweite Template im Falle vom Aufruf <em>f(i, (int</em><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="😉"
    /> 0)* stärker spezialisiert ist, und im Falle vom Aufruf <em>f(i)</em> nicht?</p>
<p>CStoll schrieb:</p>
<blockquote>
<p>Aber das steht doch auch in dem Satz, den du dort zitiert hast:</p>
<blockquote>
<p>The presence of unused ellipsis <strong>and default arguments</strong> has no effect on the partial ordering of function templates</p>
</blockquote>
</blockquote>
<p>Ja, ich habe den Satz gelesen. Nur kompiliert Comeau C/C++ 4.3.3 folgendes:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp;) {}

template &lt;typename T&gt;
void f(T const&amp;, typename T::some_type* = 0) {}

struct X { typedef void some_type; };

int main()
{
	X x;
	f(x); // Comeau C/C++ 4.3.3 - OK
	       // VC++ 8.0 - ambiguous call to overloaded function
}
</code></pre>
<p>Und Comeau C/C++ 4.3.3 ist der Standard-kompatibelste Compiler der Welt. <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/1045489</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045489</guid><dc:creator><![CDATA[igna]]></dc:creator><pubDate>Wed, 26 Apr 2006 09:21:24 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 09:25:26 GMT]]></title><description><![CDATA[<p>Und wohin wird dieser Aufruf dabei aufgelöst?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1045491</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045491</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 26 Apr 2006 09:25:26 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 09:40:34 GMT]]></title><description><![CDATA[<p>HumeSikkins schrieb:</p>
<blockquote>
<p>die partielle Ordnung wird nur auf die &quot;viable functions&quot; angewendet, also auf die Funktionen, die potentiell aufrufbar sind.</p>
</blockquote>
<p>Ja, anscheinend ist es so. Nur heisst der Paragraf 14.5.5.2 &quot;Partial ordering of function templates&quot; und nicht &quot;Partial ordering of viable template functions&quot;, daher meine Frage.</p>
<p>HumeSikkins schrieb:</p>
<blockquote>
<p>Für den Aufruf:</p>
<pre><code class="language-cpp">f(42, (int**)0);
</code></pre>
<p>hingegen gibt es überhaupt nur eine Kandidatenfunktion.</p>
</blockquote>
<p>Entschuldigung, ich sollte das Beispiel sorgfältiger konstruieren. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1045505</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045505</guid><dc:creator><![CDATA[igna]]></dc:creator><pubDate>Wed, 26 Apr 2006 09:40:34 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 09:56:14 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Und wohin wird dieser Aufruf dabei aufgelöst?</p>
</blockquote>
<p>In das zweite Funktionstemplate.</p>
<p>Ich verwende Comeau C/C++ Online, der nicht linkt, deswegen habe ich folgendes ausprobiert:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp; x) { x.test; } // OK

template &lt;typename T&gt;
void f(T const&amp; x, typename T::some_type* = 0) {}

struct X { typedef void some_type; };

int main()
{
	X x;
	f(x);
}
</code></pre>
<pre><code class="language-cpp">template &lt;typename T&gt;
void f(T const&amp; x) {}

template &lt;typename T&gt;
void f(T const&amp; x, typename T::some_type* = 0) { x.test; } // error: class &quot;X&quot; has no member &quot;test&quot;

struct X { typedef void some_type; };

int main()
{
	X x;
	f(x);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1045526</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045526</guid><dc:creator><![CDATA[igna]]></dc:creator><pubDate>Wed, 26 Apr 2006 09:56:14 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 10:29:16 GMT]]></title><description><![CDATA[<p>Interessant. Bei deinem neuen Beispiel wählt der Comeau-Compiler das zweite Template. Warum er das tut ist mir unklar. So wie ich die Regeln verstehe, sollte der Aufruf mehrdeutig sein.</p>
<p>Beide Templates sind anwendbar. Der Default-Parameter des zweiten Templates wird benutzt und ist damit für die Ordnung unerheblich. Damit sind die beiden Templates ordnungs-technisch aber identisch.<br />
Der Parameter typename T::some_type ist außerdem ein sogenannter &quot;non deduced context&quot;. Er wird also nicht automatisch hergeleitet sondern muss entweder explizit angegeben werden oder zu vorherhigen Auflösung passen.</p>
<p>igna schrieb:</p>
<blockquote>
<p>HumeSikkins schrieb:</p>
<blockquote>
<p>die partielle Ordnung wird nur auf die &quot;viable functions&quot; angewendet, also auf die Funktionen, die potentiell aufrufbar sind.</p>
</blockquote>
<p>Ja, anscheinend ist es so. Nur heisst der Paragraf 14.5.5.2 &quot;Partial ordering of function templates&quot; und nicht &quot;Partial ordering of viable template functions&quot;, daher meine Frage.</p>
</blockquote>
<p>In 14.5.5.2 steht aber auch, dass Partial ordering auf das Ergebnis von 14.8.2 angewendet wird. Partial ordering wird also verwendet, nachdem Template Argument Deduction mehr als ein Template-Deklaration für einen Aufruf gefunden hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1045549</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045549</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Wed, 26 Apr 2006 10:29:16 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 10:32:04 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/12481">@igna</a><br />
Wenn du in deinem Beispiel einen Rückgabewert einbaust, siehst du leichter, welches Template der Comau auswählt:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
int f(T const&amp;) {return 0;}

template &lt;typename T&gt;
void f(T const&amp;, typename T::some_type* = 0) {}

struct X { typedef void some_type; };

int main()
{
    X x;
    int i = f(x); // Comeau: Error, &quot;void&quot; cannot be used to initialize &quot;int&quot;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1045552</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045552</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Wed, 26 Apr 2006 10:32:04 GMT</pubDate></item><item><title><![CDATA[Reply to Partial ordering of function templates and default arguments on Wed, 26 Apr 2006 12:04:49 GMT]]></title><description><![CDATA[<p>Nur weil der Comeau extrem standardkonform ist, heißt das doch noch lange nicht, dass er sich in jeder Situation richtig verhält, könnt ja auch sein, dass er hier keinen Fehler liefert durch nen Bug.<br />
Der Standard gibt jedenfalls keine Regel an, nach welcher das eine Template spezialisierter als das andere ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1045619</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1045619</guid><dc:creator><![CDATA[CCompiler]]></dc:creator><pubDate>Wed, 26 Apr 2006 12:04:49 GMT</pubDate></item></channel></rss>