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 definition inside the class 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 inside the class.
However, for reasons of uniformity (there are other friend functions which I need to define outside) I would like to define this function outside of the class.
Is there a “trick” to make an outside of class definition of the function work?