Implicit conversion lookup on template fails for out-of-line defined friend function
The following code

    #include <cassert>
    #include <cstddef>
    
    template <typename T>
    struct foo {
        foo(std::nullptr_t) { }
        //friend bool operator ==(foo lhs, foo rhs) { return true; }
    
        template <typename U>
        friend bool operator ==(foo<U> lhs, foo<U> rhs);
    };
    
    template <typename T>
    inline bool operator ==(foo<T> lhs, foo<T> rhs) { return true; }
    
    int main() {
        foo<int> p = nullptr;
        assert(p == nullptr);
    }

 fails to compile with the error message

> foo.cpp:18:5: error: no match for '`operator==`' in '`p == nullptr`'  
> foo.cpp:18:5: note: candidate is:  
> foo.cpp:14:13: note: `template<class T> bool operator==(foo<T>, foo<T>)`  
> foo.cpp:14:13: note:   template argument deduction/substitution failed:  
> foo.cpp:18:5: note:   mismatched types '`foo<T>`' and '`std::nullptr_t`'  

However, if I use the inline definition of the function instead, the code works as expected.

Let me say that **I understand the error message:** the template argument `T` cannot be deduced for the type of `nullptr` (incidentally, `decltype(*nullptr)` doesn’t compile). Furthermore, this can be fixed here by just defining the function inline.

However, for reasons of uniformity (there are other friend functions which I *need* to define out of line) I would like to define this function outside of the class.

**Is there a “trick” to make an out of line definition of the function work?**
Implicit conversion lookup on template fails for out-of-line defined friend function
===

The following code

    #include <cassert>
    #include <cstddef>
    
    template <typename T>
    struct foo {
        foo(std::nullptr_t) { }
        //friend bool operator ==(foo lhs, foo rhs) { return true; }
    
        template <typename U>
        friend bool operator ==(foo<U> lhs, foo<U> rhs);
    };
    
    template <typename T>
    inline bool operator ==(foo<T> lhs, foo<T> rhs) { return true; }
    
    int main() {
        foo<int> p = nullptr;
        assert(p == nullptr);
    }

 fails to compile with the error message

> foo.cpp:18:5: error: no match for '`operator==`' in '`p == nullptr`'  
> foo.cpp:18:5: note: candidate is:  
> foo.cpp:14:13: note: `template<class T> bool operator==(foo<T>, foo<T>)`  
> foo.cpp:14:13: note:   template argument deduction/substitution failed:  
> foo.cpp:18:5: note:   mismatched types '`foo<T>`' and '`std::nullptr_t`'  

However, if I use the inline definition of the function instead, the code works as expected.

Let me say that **I understand the error message:** the template argument `T` cannot be deduced for the type of `nullptr` (incidentally, `decltype(*nullptr)` doesn’t compile). Furthermore, this can be fixed here by just defining the function inline.

However, for reasons of uniformity (there are other friend functions which I *need* to define out of line) I would like to define this function outside of the class.

**Is there a “trick” to make an out of line definition of the function work?**