Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is a common problem when befriending non-member functions with templates. The <code>friend</code> declaration inside the <code>TemplateClass</code> does not befriend your <code>swap</code> template, but rather a non-templated free function <code>swap</code> that takes <code>TemplateClass&lt;T&gt;</code> for which ever <code>T</code> the template is instantiated (i.e. the specialization <code>TemplateClass&lt;int&gt;</code> will befriend a free function <code>void swap( TemplateClass&lt;int&gt;&amp;,TemplateClass&lt;int&gt;&amp; );</code> that is not templated).</p> <p>The best solution is to provide the <code>swap</code> definition inlined inside the class template definition, as that will make the compiler generate a non-templated <code>swap</code> function for the exact type whenever needed. As another positive side effect, that <code>swap</code> function will only be found during Argument Dependent Lookup, so it will not take part of overload resolution for anything that does not involve your template.</p> <p>Other alternatives are befriending the whole <code>swap</code> template function, or befriending the particular specialization of the <code>swap</code> function when applied to the same <code>T</code> that the template has been instantiated with. The first of the options is simple in code, but it grants access to <em>all</em> of the specializations of the <code>swap</code> template, and that might have bad side effects. Befriending the particular <code>swap</code> specialization solves that issue, but is a bit more complex to implement (you need to forward declare the class template, then the <code>swap</code> template, then define the class template, and finally define the <code>swap</code> template).</p> <p>More on this in this other <a href="https://stackoverflow.com/questions/4660123/overloading-friend-operator-for-template-class/4661372#4661372">answer</a>, where the different options and syntaxes are explained with more detail.</p> <p>As to the particular error message of <code>unresolved external</code>, that is due to how identifier lookup works. When you used <code>swap(*this,other);</code> inside a member function, lookup starts inside the class, and tries to find an appropriate <code>swap</code>. It first looks in the class context and finds the declaration of the <code>friend</code> free function, so lookup does not continue going outwards and adds a dependency to that particular free function. It adds the dependency and waits for the linker to locate the appropriate symbol. Because the compiler never considered the templated <code>swap</code> at namespace level, it never actually instantiated it, but even if it had instantiated that template, the dependency inside the <code>operator=</code> member function is on a free function, not that specialization.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload