Implementing non-member generic function for specific nested class of a class template
<p>I have the following class:</p>

<pre><code>template&lt;int P&gt;
struct A {
    struct B {
        auto abs() const { return 1; }
    };
};
</code></pre>

<p>Specifically <code>A</code> is supposed to be the finite field of integers modulo P, and <code>B</code> is the class representing elements from this finite field. Then I have a generic implementation of the extended GCD algorithm which is supposed to use the <code>abs</code> function. The problem I want the extended GCD algorithm implementation to work on basic types (int, long, etc), as well as <code>A&lt;P&gt;::B</code>. So I need to implement a non-member <code>abs</code> that will call <code>A&lt;P&gt;::B::abs</code>. I tried a three techniques, two of them don't work and one that works but is not suitable.</p>

<p>Technique 1 (doesn't work): use argument-dependent lookup (ADL). Define the following <strong>inside</strong> the body of <code>A</code> but outside the body of <code>B</code>:</p>

<pre><code>auto abs(B const &amp;e) { return e.abs(); }
</code></pre>

<p>It won't work since ADL looks only inside namespaces not class scopes. <strong>UPDATE</strong> : ADL doesn't work here because <code>abs</code> is an instance method. However as per T.C.'s answer, if you make it a friend function it works correctly and ADL finds it!</p>

<p>Technique 2 (doesn't work): use constrained function template in global or namespace scope:</p>

<pre><code>template&lt;int P&gt;
auto abs(typename A&lt;P&gt;::B const &amp;e) { return e.abs(); }
</code></pre>

<p>This will also not work because <code>P</code> is in a non-deduced context.</p>

<p>Technique 3 (works, but not satisfactory): use unconstrained function template in global or namespace scope:</p>

<pre><code>template&lt;typename T&gt;
auto abs(T const &amp;e) { return e.abs(); }
</code></pre>

<p>This works. However, it is unconstrained. I would like to restrict instantiations of this function template only to <code>A&lt;P&gt;</code> (for <code>P</code> unknown beforehand), and other class templates (for polynomial rings and field extensions). The problem is I am not sure how to use SFINAE if <code>P</code> is in a non-deduced context. </p>