<?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[argument-dependent lookup + namespace]]></title><description><![CDATA[<p>Darf das argument-dependent lookup sich auch über namespaces hinwegsetzen?</p>
<p>bsp.:</p>
<pre><code class="language-cpp">#include &lt;string&gt;

int main()
{
  std::string a;
  std::string b;

  swap(a, b);
}
</code></pre>
<p>kompiliert unter msvc</p>
<p>das es am adl liegt, schließe ich daraus:</p>
<pre><code class="language-cpp">#include &lt;string&gt;

int main()
{
  int a = 0;
  int b = 1;

  swap(a, b);
}
</code></pre>
<p>-&gt;</p>
<p>MSVC 9 schrieb:</p>
<blockquote>
<p>error C3861: 'swap': identifier not found</p>
</blockquote>
<p>Für spezialisierte fkt scheint es also auch ohne namespace zu gehen - ist das richtig oder ist das ein feature/bug des msvc?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/245373/argument-dependent-lookup-namespace</link><generator>RSS for Node</generator><lastBuildDate>Fri, 18 Sep 2026 15:38:04 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/245373.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 13 Jul 2009 13:12:24 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 13:12:24 GMT]]></title><description><![CDATA[<p>Darf das argument-dependent lookup sich auch über namespaces hinwegsetzen?</p>
<p>bsp.:</p>
<pre><code class="language-cpp">#include &lt;string&gt;

int main()
{
  std::string a;
  std::string b;

  swap(a, b);
}
</code></pre>
<p>kompiliert unter msvc</p>
<p>das es am adl liegt, schließe ich daraus:</p>
<pre><code class="language-cpp">#include &lt;string&gt;

int main()
{
  int a = 0;
  int b = 1;

  swap(a, b);
}
</code></pre>
<p>-&gt;</p>
<p>MSVC 9 schrieb:</p>
<blockquote>
<p>error C3861: 'swap': identifier not found</p>
</blockquote>
<p>Für spezialisierte fkt scheint es also auch ohne namespace zu gehen - ist das richtig oder ist das ein feature/bug des msvc?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742110</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742110</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 13 Jul 2009 13:12:24 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 13:18:15 GMT]]></title><description><![CDATA[<p>unskilled schrieb:</p>
<blockquote>
<p>Darf das argument-dependent lookup sich auch über namespaces hinwegsetzen?</p>
</blockquote>
<p>Das ist ja ein Feature von ADL. <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>Es wird unter anderem auch im Namensraum der Parametertypen gesucht, ob die entsprechende Funktion vorhanden ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742115</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742115</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 13 Jul 2009 13:18:15 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 13:21:57 GMT]]></title><description><![CDATA[<p>ADL setzt sich nicht über einen <code>namespace</code> hinweg, sondern es garantiert, dass auch im <code>namespace</code> der Argumente gesucht wird.</p>
<p>Im ersten Beispiel wird also auch im <code>namespace std</code> gesucht, weil von dort die Klasse <code>string</code> herkommt.<br />
Im zweiten Beispiel gehören die Typen aber keinem <code>namespace</code> an. Also wird nur global gesucht und nichts gefunden.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742120</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742120</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 13 Jul 2009 13:21:57 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 13:24:30 GMT]]></title><description><![CDATA[<p>ty - wieder was dazu gelernt ^^</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742123</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742123</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 13 Jul 2009 13:24:30 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 14:55:40 GMT]]></title><description><![CDATA[<p>Ein dazu passender Link: <a href="http://www.gotw.ca/publications/mill08.htm" rel="nofollow">Namespaces and the Interface Principle</a></p>
<p>Wenn man <code>swap</code> noch &quot;generisch&quot; benutzen will, sollte man das dann so machen:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void rotate_left(T &amp; a, T &amp; b, T &amp; c)
{
  using std::swap;
  swap(a,b);
  swap(b,c);
}
</code></pre>
<p>Beachte: Nur ein unqualifiziertes <code>swap</code> erlaubt ADL. So kann zB das folgende <code>swap</code> noch für <code>T</code> = <code>my_type</code> über ADL gefunden werden:</p>
<pre><code class="language-cpp">namespace my_namespace {
  class my_type
  {
    int * p;
  public:
    explicit my_type(int*p);
    my_type(my_type const&amp;);
    my_type&amp; operator=(my_type const&amp;);
    ~my_type();
    void swap(my_type &amp; with);
  };

  inline void swap(my_type &amp; a, my_type &amp; b) { a.swap(b); }
}
</code></pre>
<p>Trotzdem wird das Template von oben noch für fundamentale Typen funktionieren, weil <code>std::swap</code> per <code>using</code> -Deklaration in den Geltungsbereich geholt wurde.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742183</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742183</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Mon, 13 Jul 2009 14:55:40 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 15:33:00 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Ein dazu passender Link: <a href="http://www.gotw.ca/publications/mill08.htm" rel="nofollow">Namespaces and the Interface Principle</a></p>
</blockquote>
<p>ty</p>
<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Wenn man <code>swap</code> noch &quot;generisch&quot; benutzen will, sollte man das dann so machen:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void rotate_left(T &amp; a, T &amp; b, T &amp; c)
{
  using std::swap;
  swap(a,b);
  swap(b,c);
}
</code></pre>
</blockquote>
<p>Hab ich zwar auch schon immer so gemacht aber jetzt eben erst so richtig verstanden, warum man es wirklich so macht - davor dachte ich halt immer, dass ein mehr spezialisiertes swap nur gefunden werden kann, wenn es im globalen(oder in diesem - also im aktuellen) scope liegt...</p>
<p>also danke noch mal : &gt;</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742229</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742229</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 13 Jul 2009 15:33:00 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 20:03:52 GMT]]></title><description><![CDATA[<p>Hm, gerade noch eine passende Frage dazu:</p>
<p>Überladet ihr im Allgemeinen ein globales (bzw. im eigenen Namensraum) <code>swap()</code> für euren Typen und hofft darauf, dass der Anwender jeweils <code>using std::swap; swap(a,b);</code> schreibt, oder spezialisiert ihr das <code>std::swap</code> -Template und spekuliert, dass der Anwender <code>std::</code> angibt? <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>Welche Varianten würdet ihr hier wählen?</p>
<pre><code class="language-cpp">class MyClass {};

// 1)
void swap(MyClass&amp;, MyClass&amp;)
{
	std::cout &lt;&lt; &quot;swap&quot; &lt;&lt; std::endl;
}

// 2)
template &lt;&gt;
void std::swap(MyClass&amp;, MyClass&amp;)
{
	std::cout &lt;&lt; &quot;swap&lt;MyClass&gt;&quot; &lt;&lt; std::endl;
}

int main() 
{ 
	MyClass x, y;

	// A)
	swap(x, y);

	// B)
	std::swap(x, y);

	// C)
	using std::swap;
	swap(x, y);
}
</code></pre>
<p>Ist das <code>std::</code> bei 2) so eigentlich okay und gibt es einen Unterschied zu einem umschliessenden <code>namespace std {}</code> ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742374</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742374</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 13 Jul 2009 20:03:52 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 21:00:33 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Hm, gerade noch eine passende Frage dazu:</p>
<p>Überladet ihr im Allgemeinen ein globales (bzw. im eigenen Namensraum) <code>swap()</code> für euren Typen und hofft darauf, dass der Anwender jeweils <code>using std::swap; swap(a,b);</code> schreibt, oder spezialisiert ihr das <code>std::swap</code> -Template und spekuliert, dass der Anwender <code>std::</code> angibt? <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>Ich spezialisiere std::swap so dass es meine eigene swap-Routine aufruft. Damit sind alle Möglichkeiten abgedeckt. Denn leider schreibt der Anwender nicht immer using std::swap sondern ruf std::swap direkt explizit auf (selbst einige STL-Implementierungen machen das leider).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742410</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742410</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 13 Jul 2009 21:00:33 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 21:15:21 GMT]]></title><description><![CDATA[<p>Ah danke, ja das scheint noch Sinn zu machen. Allerdings ist es etwas mühsam, jeweils drei Funktionen (inklusive Memberfunktion) bereitzustellen.</p>
<p>Hm... Irgendwie gerate ich da in Versuchung eines bösen Makro-Hacks... :p<br />
Aber vorläufig werde ich es wohl direkt mit deiner Methode versuchen, allzu schlimm sind die paar Zeilen Code ja nicht. <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/1742420</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742420</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 13 Jul 2009 21:15:21 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 21:53:45 GMT]]></title><description><![CDATA[<p><code>swap</code> im eigenen Namespace selbst zu definieren, ist nur dann nötig, wenn man Template-Klassen swappen will.</p>
<p>Es ist nämlich erlaubt <code>std::swap</code> zu spezialisieren, aber nicht zusätzliche Overloads zu erzeugen.</p>
<p>Da Funktions-Templates nicht partiell spezialisiert werden können, muss für Dinge wie <code>swap(boost::shared_ptr&lt;T&gt;&amp;, boost::shared_ptr&lt;T&gt;&amp;)</code> ein Overload her.<br />
Und da man diesen Overload wie gesagt (leider) nicht in <code>std::</code> machen darf, muss er in den Namespace der <code>shared_ptr&lt;&gt;</code> definiert, damit er über ADL gefunden wird. D.h. in diesem Fall &quot;boost&quot;.<br />
(Technisch geht es natürlich <code>std::swap</code> zu überladen, aber es ist halt nicht &quot;erlaubt&quot;)</p>
<p>Daher sollte man IMO auch die <code>using std::swap; swap(a, b);</code> Variante verwenden, wenn man selbst &quot;swappenden&quot; Code schreibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742427</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742427</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 13 Jul 2009 21:53:45 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 21:31:13 GMT]]></title><description><![CDATA[<p>Für &quot;normale&quot; Klassen (also keine Klassentemplates) kann man beides machen: eine freie swap-Funktion im gleichen Namensraum wie die Klasse plus eine Spezialisierung für std::swap. Da es keine partiellen Spezialisierungen für Funktions-Templates gibt, geht das mit Klassentemplates nicht mehr.</p>
<p>Das Spezialisieren von Funktionstemplates ist etwas, was ich vermeide. Überladen finde ich da sinvoller. Aber das ist ja im std-Namensraum illegal.</p>
<p>Mit dem, was die Leute sich für C++0x überlegt haben, wird auch eine einzige swap-Funktion im eigenen Namensraum reichen.</p>
<blockquote>
<p>Ist das <code>std::</code> bei 2) so eigentlich okay und gibt es einen Unterschied zu einem umschliessenden <code>namespace std {}</code> ?</p>
</blockquote>
<p>Ich glaube, das ist nicht erlaubt.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742428</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742428</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Mon, 13 Jul 2009 21:31:13 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 21:58:14 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Mit dem, was die Leute sich für C++0x überlegt haben, wird auch eine einzige swap-Funktion im eigenen Namensraum reichen.</p>
</blockquote>
<p>Das würde es momentan eigentlich auch, wenn sich der Aufrufer etwas achten würde. Oder was meinst du konkret?</p>
<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Ich glaube, das ist nicht erlaubt.</p>
</blockquote>
<p>Das Gefühl habe ich irgendwie auch. Ich habe diese Schreibweise bisher gar noch nie verwendet, aber mal spontan ausprobiert, und es hat normal kompiliert (MSVC++). Weiss jemand Genaueres darüber?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742439</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742439</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 13 Jul 2009 21:58:14 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 22:10:18 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Irgendwie gerate ich da in Versuchung eines bösen Makro-Hacks... :p</p>
</blockquote>
<p>Nur halb böse <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="😉"
    /> friend-injection machts doch auch, zumindest für die ADL-Swap-Funktion. Siehe boost::operators (wie dies machen hab ich im dritten Operator-Artikel erklärt):</p>
<pre><code class="language-cpp">namespace SomeWhere
{
template &lt;class T&gt;
struct Swappable
{
  friend void swap(T&amp; lhs, T&amp; rhs)
  { lhs.swap(rhs); }
};

} //end ns SomeWhere

namespace SomeWhereElse
{
  class Foo : private SomeWhere::Swappable&lt;Foo&gt;
  {
  public: 
    void swap(Foo&amp; rhs);
  }
}

int main()
{
  using SomeWhereElse::Foo;
  Foo a, b;
  swap(a, b);
}
</code></pre>
<p>Leider gehts für std::swap nicht: man darf keine qualifizierten Funktionen als friends definieren, erst recht dürfen keine Template-Spezialisierungen während einer friend-Deklaration definiert werden. Leider kann man auch keine partielle Spezialisierung eines Funktionstemplates machen, schön wäre folgendes:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
void ::std::swap&lt;SomeWhere::Swappable&lt;T&gt; &gt;(Swappable&lt;T&gt;&amp; lhs, Swappable&lt;T&gt;&amp; rhs)
{
  (static_cast&lt;T&amp;&gt;(lhs)).swap(static_cast&lt;T&amp;&gt;(rhs));
}
</code></pre>
<p>Das hier wäre eine <em>Überladung</em>, was die verbotene Einführung einer zusätzlichen Funktion in den Namespace std wäre.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742445</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742445</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 13 Jul 2009 22:10:18 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 22:16:28 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Ich glaube, das ist nicht erlaubt.</p>
</blockquote>
<p>Das Gefühl habe ich irgendwie auch. Ich habe diese Schreibweise bisher gar noch nie verwendet, aber mal spontan ausprobiert, und es hat normal kompiliert (MSVC++). Weiss jemand Genaueres darüber?</p>
</blockquote>
<p>Um euren Glauben und euer Gefühl zu bestätigen der entsprechende Ausschnitt aus dem Standard:</p>
<p>ISO/IEC 14882 §17.4.3/2 schrieb:</p>
<blockquote>
<p>An explicit specialization shall be declared in the namespace of which the template is a member [...] Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later in the namespace in which the explicit specialization was declared, or in a namespace that encloses the one in which the explicit specialization was declared.</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1742451</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742451</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 13 Jul 2009 22:16:28 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Mon, 13 Jul 2009 22:52:40 GMT]]></title><description><![CDATA[<p>hustbaer, auch dir danke für die Erklärungen, ich hab deinen Post vorhin gar nicht gesehen.</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Daher sollte man IMO auch die <code>using std::swap; swap(a, b);</code> Variante verwenden, wenn man selbst &quot;swappenden&quot; Code schreibt.</p>
</blockquote>
<p>Würde sich dann evtl. sowas empfehlen?</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void adl_swap(T&amp; lhs, T&amp; rhs)
{
    using std::swap;
    swap(lhs, rhs);
}
</code></pre>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Nur halb böse <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="😉"
    /> friend-injection machts doch auch, zumindest für die ADL-Swap-Funktion.</p>
</blockquote>
<p>Stimmt. Ich hab mich nämlich zuerst auch gefragt, wie die <em>Boost.Operators</em>-Entwickler freie Funktionen über Basisklassen bereitstellen wollen... <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="😉"
    /><br />
Recht praktisch, die Technik.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Leider gehts für std::swap nicht: man darf keine qualifizierten Funktionen als friends definieren.</p>
</blockquote>
<p>Sorry, hier bin ich nicht ganz nachgekommen, inwiefern meinst du &quot;qualifiziert&quot;? Durch den Namensraum?</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Leider kann man auch keine partielle Spezialisierung eines Funktionstemplates machen, schön wäre folgendes</p>
</blockquote>
<p>Das sollte doch auch mit dem neuen Standard kommen, wenn ich mich nicht täusche...</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Um euren Glauben und euer Gefühl zu bestätigen der entsprechende Ausschnitt aus dem Standard:</p>
<p>ISO/IEC 14882 §17.4.3/2 schrieb:</p>
<blockquote>
<p>An explicit specialization shall be declared in the namespace of which the template is a member [...] Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later in the namespace in which the explicit specialization was declared, or in a namespace that encloses the one in which the explicit specialization was declared.</p>
</blockquote>
</blockquote>
<p>Wenn ich das richtig verstehe, führt das <code>std::</code> bei <code>void std::swap</code> also gar nicht zur Einbettung in den Namensraum. Das habe ich bisher falsch interpretiert. Wozu wird diese Schreibweise (im Gegensatz zum konventionellen, umschliessenden Namensraum) verwendet?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742454</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742454</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 13 Jul 2009 22:52:40 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Tue, 14 Jul 2009 08:36:13 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Leider gehts für std::swap nicht: man darf keine qualifizierten Funktionen als friends definieren.</p>
</blockquote>
<p>Sorry, hier bin ich nicht ganz nachgekommen, inwiefern meinst du &quot;qualifiziert&quot;? Durch den Namensraum?</p>
</blockquote>
<p>Ist im Grunde das Selbe wie der Auszug aus dem Standard den ich gepostet habe. Du kannst per friend-injection keine Funktion in einen anderen Namespace definieren. Oder andersrum: wenn du einen qualifizierten (also im Grunde alles mit :: drin) als friend deklarierst, kann es eben nur eine Deklaration und keine Definition sein. Definitionen beziehen sich immr auf den umgebenden Namespace, alles andere kann nur dort definiert werden wo es wirklich hingehört.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Um euren Glauben und euer Gefühl zu bestätigen der entsprechende Ausschnitt aus dem Standard:</p>
<p>ISO/IEC 14882 §17.4.3/2 schrieb:</p>
<blockquote>
<p>An explicit specialization shall be declared in the namespace of which the template is a member [...] Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later in the namespace in which the explicit specialization was declared, or in a namespace that encloses the one in which the explicit specialization was declared.</p>
</blockquote>
</blockquote>
<p>Wenn ich das richtig verstehe, führt das <code>std::</code> bei <code>void std::swap</code> also gar nicht zur Einbettung in den Namensraum. Das habe ich bisher falsch interpretiert. Wozu wird diese Schreibweise (im Gegensatz zum konventionellen, umschliessenden Namensraum) verwendet?[/quote] Die Schreibweise kann wie der Text besagt dazu verwendet werden, um im globalen namespace eine Spezialisierung von std::swap zu <em>definieren</em> - aber nur wenn sie orher innerhalb von namespace std <em>deklariert</em> wurde. MSVC scheint da etwas freizügiger zu sein, da er die Definition auch in anderen Namespaces und ohne vorherige korrekt plazierte Deklaration schluckt.</p>
<pre><code class="language-cpp">namespace std
{
  template&lt;&gt; void swap&lt;Foo&gt;(Foo&amp;, Foo&amp;);
  template&lt;&gt; void swap&lt;Bla&gt;(Bla&amp;, Bla&amp;);
}

template&lt;&gt; void std::swap&lt;Foo&gt;(Foo&amp;, Foo&amp;) {} //OK
template&lt;&gt; void std::swap&lt;Bar&gt;(Bar&amp;, Bar&amp;) {} //FEHLER - wurde nicht in std deklariert

namespace OuterSpace 
{
  template&lt;&gt; void ::std::swap&lt;Bla&gt;(Bla&amp;, Bla&amp;) {} //FEHLER - OuterSpace ist kein umgebender namespace von std
</code></pre>
<p>}</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742542</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742542</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 14 Jul 2009 08:36:13 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Tue, 14 Jul 2009 10:03:18 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Leider kann man auch keine partielle Spezialisierung eines Funktionstemplates machen, schön wäre folgendes:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
void swap&lt;SomeWhere::Swappable&lt;T&gt; &gt;(Swappable&lt;T&gt;&amp; lhs, Swappable&lt;T&gt;&amp; rhs)
{
  (static_cast&lt;T&amp;&gt;(lhs)).swap(static_cast&lt;T&amp;&gt;(rhs));
}
</code></pre>
<p>Das hier wäre eine <em>Überladung</em>, was die verbotene Einführung einer zusätzlichen Funktion in den Namespace std wäre.</p>
</blockquote>
<p>Die &lt;&gt;-Klammern hinter swap deuten auf eine Spezialisierung hin, die in diesem Fall partiell und damit illegal ist. Ein neues Funktionstemplate müsste man ohne diese Klammern schreiben.</p>
<p>Ich bin kein Freund von Funktions-Template-Spezialisierungen. Die werden zB nicht bei der Auflösung von Überladungen beachtet, auch wenn sie &quot;spezieller&quot; sind. Beispiel:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

template&lt;typename U&gt;
struct s{};

template&lt;typename T&gt;
void foo(T x) {
  std::cout &lt;&lt; &quot;1\n&quot;;
}

template&lt;&gt;
void foo&lt;s&lt;int&gt; &gt;(s&lt;int&gt; x) {
  std::cout &lt;&lt; &quot;2\n&quot;;
}

template&lt;typename U&gt;
void foo(s&lt;U&gt; x) {
  std::cout &lt;&lt; &quot;3\n&quot;;
}

int main() {
  foo(s&lt;int&gt;());
}
</code></pre>
<p>Hier sind 2 Funktions-Templates überladen worden, wobei eines davon für s&lt;int&gt; spezialisiert wurde. Ist die Ausgabe des Programms 1, 2 oder 3? Obwohl eigentlich die Spezialisierung des ersten Templates am &quot;besten passen&quot; sollte, richtet sich die &quot;overload resolution&quot; nicht danach, was es alles so für Spezialisierungen gibt. Die Auflösung wird in diesem Fall durch die &quot;partial ordering&quot;-Regeln bestimmt, die sagen, dass das zweite Funktionstemplate <code>template&lt;typename U&gt; void foo(s&lt;U&gt;)</code> spezieller als das erste Funktionstemplate <code>template&lt;typename T&gt; void foo(T)</code> ist. Dementsprechend ist die Ausgabe des Programms &quot;3&quot;.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Mit dem, was die Leute sich für C++0x überlegt haben, wird auch eine einzige swap-Funktion im eigenen Namensraum reichen.</p>
</blockquote>
<p>Das würde es momentan eigentlich auch, wenn sich der Aufrufer etwas achten würde. Oder was meinst du konkret?</p>
</blockquote>
<p>Stimmt. Man wird auch immer noch nicht davon abgehalten, ADL explizit durch Qualifizierungen auszuschalten. Mit Concepts ist es aber wahrscheinlich schwieriger, in der Hinsicht etwas falsch zu machen:</p>
<pre><code class="language-cpp">#include &lt;concepts&gt;  // std::Swappable
#include &lt;algorithm&gt; // std::swap

template&lt;typename T&gt; requires std::Swappable&lt;T&gt;
void rotate_left(T &amp; a, T &amp; b, T &amp; c)
{
  swap(a,b);
  swap(b,c);
}
</code></pre>
<p>Das wird auch für fundamentale Typen funktionieren, ohne, dass ich &quot;using std::swap;&quot; schreiben muss. Man sollte nur nicht vergessen &lt;algorithm&gt; einzufügen.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1742613</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742613</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Tue, 14 Jul 2009 10:03:18 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Wed, 15 Jul 2009 13:24:42 GMT]]></title><description><![CDATA[<p>Danke für die Antworten. Concepts werden wahrscheinlich auch sonst einiges zur Schnittstellenvereinheitlichung beitragen. Aber für die nächste Zeit scheint mir pumuckls Vorschlag noch recht flexibel, die automatische Codegenerierung durch Basisklassen ist wirklich nützlich.</p>
<p>Aber so nebenbei: Wird das wirklich <code>std::Swappable</code> heissen oder war das mehr ein Beispiel? Die Grosschreibung von Bezeichnern im Standard erstaunt mich drum etwas... <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/1743515</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1743515</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 15 Jul 2009 13:24:42 GMT</pubDate></item><item><title><![CDATA[Reply to argument-dependent lookup + namespace on Wed, 15 Jul 2009 14:26:37 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Aber so nebenbei: Wird das wirklich <code>std::Swappable</code> heissen oder war das mehr ein Beispiel? Die Grosschreibung von Bezeichnern im Standard erstaunt mich drum etwas... <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>Es sieht ganz so aus. std::Swappable gibt es wirklich im <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf" rel="nofollow">aktuellen Entwurf</a>. Ich hatte es extra nachgeguckt (Kapitel 20.2).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1743571</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1743571</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Wed, 15 Jul 2009 14:26:37 GMT</pubDate></item></channel></rss>