<p><code>std::swap()</code> is used by many std containers (such as <code>std::list</code> and <code>std::vector</code>) during sorting and even assignment.</p>

<p>But the std implementation of <code>swap()</code> is very generalized and rather inefficient for custom types.</p>

<p>Thus efficiency can be gained by overloading <code>std::swap()</code> with a custom type specific implementation. But how can you implement it so it will be used by the std containers?</p>

[{'answer_id': 11599, 'author': 'Wilka', 'author_id': 1367, 'author_profile': 'https://Stackoverflow.com/users/1367', 'pm_score': 6, 'selected': False, 'text': "<p>You're not allowed (by the C++ standard) to overload std::swap, however you are specifically allowed to add template specializations for your own types to the std namespace. E.g.</p>\n\n<pre><code>namespace std\n{\n    template&lt;&gt;\n    void swap(my_type&amp; lhs, my_type&amp; rhs)\n    {\n       // ... blah\n    }\n}\n</code></pre>\n\n<p>then the usages in the std containers (and anywhere else) will pick your specialization  instead of the general one.</p>\n\n<p>Also note that providing a base class implementation of swap isn't good enough for your derived types. E.g. if you have</p>\n\n<pre><code>class Base\n{\n    // ... stuff ...\n}\nclass Derived : public Base\n{\n    // ... stuff ...\n}\n\nnamespace std\n{\n    template&lt;&gt;\n    void swap(Base&amp; lha, Base&amp; rhs)\n    {\n       // ...\n    }\n}\n</code></pre>\n\n<p>this will work for Base classes, but if you try to swap two Derived objects it will use the generic version from std because the templated swap is an exact match (and it avoids the problem of only swapping the 'base' parts of your derived objects).</p>\n\n<p>NOTE: I've updated this to remove the wrong bits from my last answer. D'oh! (thanks puetzk and j_random_hacker for pointing it out)</p>\n"}, {'answer_id': 109613, 'author': 'puetzk', 'author_id': 14312, 'author_profile': 'https://Stackoverflow.com/users/14312', 'pm_score': 5, 'selected': False, 'text': '<p>While it\'s correct that one shouldn\'t generally add stuff to the std:: namespace, adding template specializations for user-defined types is specifically allowed. Overloading the functions is not. This is a subtle difference :-)</p>\n\n<blockquote>\n  <p>17.4.3.1/1\n    It is undefined for a C++ program to add declarations or definitions\n    to namespace std or namespaces with namespace std unless otherwise\n    specified.  A program may add template specializations for any\n    standard library template to namespace std. Such a specialization\n    (complete or partial) of a standard library results in undefined\n    behaviour unless the declaration depends on a user-defined name of\n    external linkage and unless the template specialization meets the\n    standard library requirements for the original template. </p>\n</blockquote>\n\n<p>A specialization of std::swap would look like:</p>\n\n<pre><code>namespace std\n{\n    template&lt;&gt;\n    void swap(myspace::mytype&amp; a, myspace::mytype&amp; b) { ... }\n}\n</code></pre>\n\n<p>Without the template&lt;> bit it would be an overload, which is undefined, rather than a specialization, which is permitted. @Wilka\'s suggest approach of changing the default namespace may work with user code (due to Koenig lookup preferring the namespace-less version) but it\'s not guaranteed to, and in fact isn\'t really supposed to (the STL implementation ought to use the fully-qualified std::swap).</p>\n\n<p>There is a <a href="http://groups.google.ca/group/comp.lang.c++.moderated/browse_thread/thread/b396fedad7dcdc81" rel="noreferrer">thread on comp.lang.c++.moderated</a> with a <strong>long</strong> dicussion of the topic. Most of it is about partial specialization, though (which there\'s currently no good way to do).</p>\n'}, {'answer_id': 2684544, 'author': 'Dave Abrahams', 'author_id': 125349, 'author_profile': 'https://Stackoverflow.com/users/125349', 'pm_score': 8, 'selected': True, 'text': '<p>The right way to overload <code>std::swap</code>\'s implemention (aka specializing it), is to write it in the same namespace as what you\'re swapping, so that it can be found via <a href="https://en.cppreference.com/w/cpp/language/adl" rel="noreferrer">argument-dependent lookup (ADL)</a>.  One particularly easy thing to do is:</p>\n<pre><code>class X\n{\n    // ...\n    friend void swap(X&amp; a, X&amp; b)\n    {\n        using std::swap; // bring in swap for built-in types\n\n        swap(a.base1, b.base1);\n        swap(a.base2, b.base2);\n        // ...\n        swap(a.member1, b.member1);\n        swap(a.member2, b.member2);\n        // ...\n    }\n};\n</code></pre>\n'}, {'answer_id': 8439357, 'author': 'Howard Hinnant', 'author_id': 576911, 'author_profile': 'https://Stackoverflow.com/users/576911', 'pm_score': 6, 'selected': False, 'text': '<p><strong>Attention Mozza314</strong></p>\n\n<p>Here is a simulation of the effects of a generic <code>std::algorithm</code> calling <code>std::swap</code>, and having the user provide their swap in namespace std.  As this is an experiment, this simulation uses <code>namespace exp</code> instead of <code>namespace std</code>.</p>\n\n<pre><code>// simulate &lt;algorithm&gt;\n\n#include &lt;cstdio&gt;\n\nnamespace exp\n{\n\n    template &lt;class T&gt;\n    void\n    swap(T&amp; x, T&amp; y)\n    {\n        printf("generic exp::swap\\n");\n        T tmp = x;\n        x = y;\n        y = tmp;\n    }\n\n    template &lt;class T&gt;\n    void algorithm(T* begin, T* end)\n    {\n        if (end-begin &gt;= 2)\n            exp::swap(begin[0], begin[1]);\n    }\n\n}\n\n// simulate user code which includes &lt;algorithm&gt;\n\nstruct A\n{\n};\n\nnamespace exp\n{\n    void swap(A&amp;, A&amp;)\n    {\n        printf("exp::swap(A, A)\\n");\n    }\n\n}\n\n// exercise simulation\n\nint main()\n{\n    A a[2];\n    exp::algorithm(a, a+2);\n}\n</code></pre>\n\n<p>For me this prints out:   </p>\n\n<pre><code>generic exp::swap\n</code></pre>\n\n<p>If your compiler prints out something different then it is not correctly implementing "two-phase lookup" for templates.</p>\n\n<p>If your compiler is conforming (to any of C++98/03/11), then it will give the same output I show.  And in that case exactly what you fear will happen, does happen.  And putting your <code>swap</code> into namespace <code>std</code> (<code>exp</code>) did not stop it from happening.</p>\n\n<p>Dave and I are both committee members and have been working this area of the standard for a decade (and not always in agreement with each other).  But this issue has been settled for a long time, and we both agree on how it has been settled.  Disregard Dave\'s expert opinion/answer in this area at your own peril.</p>\n\n<p>This issue came to light after C++98 was published.  Starting about 2001 Dave and I began to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1289.html">work this area</a>.  And this is the modern solution:</p>\n\n<pre><code>// simulate &lt;algorithm&gt;\n\n#include &lt;cstdio&gt;\n\nnamespace exp\n{\n\n    template &lt;class T&gt;\n    void\n    swap(T&amp; x, T&amp; y)\n    {\n        printf("generic exp::swap\\n");\n        T tmp = x;\n        x = y;\n        y = tmp;\n    }\n\n    template &lt;class T&gt;\n    void algorithm(T* begin, T* end)\n    {\n        if (end-begin &gt;= 2)\n            swap(begin[0], begin[1]);\n    }\n\n}\n\n// simulate user code which includes &lt;algorithm&gt;\n\nstruct A\n{\n};\n\nvoid swap(A&amp;, A&amp;)\n{\n    printf("swap(A, A)\\n");\n}\n\n// exercise simulation\n\nint main()\n{\n    A a[2];\n    exp::algorithm(a, a+2);\n}\n</code></pre>\n\n<p>Output is:</p>\n\n<pre><code>swap(A, A)\n</code></pre>\n\n<p><strong>Update</strong></p>\n\n<p>An observation has been made that:</p>\n\n<pre><code>namespace exp\n{    \n    template &lt;&gt;\n    void swap(A&amp;, A&amp;)\n    {\n        printf("exp::swap(A, A)\\n");\n    }\n\n}\n</code></pre>\n\n<p>works!  So why not use that?</p>\n\n<p>Consider the case that your <code>A</code> is a class template:</p>\n\n<pre><code>// simulate user code which includes &lt;algorithm&gt;\n\ntemplate &lt;class T&gt;\nstruct A\n{\n};\n\nnamespace exp\n{\n\n    template &lt;class T&gt;\n    void swap(A&lt;T&gt;&amp;, A&lt;T&gt;&amp;)\n    {\n        printf("exp::swap(A, A)\\n");\n    }\n\n}\n\n// exercise simulation\n\nint main()\n{\n    A&lt;int&gt; a[2];\n    exp::algorithm(a, a+2);\n}\n</code></pre>\n\n<p>Now it doesn\'t work again. :-(</p>\n\n<p>So you could put <code>swap</code> in namespace std and have it work.  But you\'ll need to remember to put <code>swap</code> in <code>A</code>\'s namespace for the case when you have a template: <code>A&lt;T&gt;</code>.  And since both cases will work if you put <code>swap</code> in <code>A</code>\'s namespace, it is just easier to remember (and to teach others) to just do it that one way.</p>\n'}]
['https://Stackoverflow.com/questions/11562', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1366/']