Die implizite Konvertierungssuche in der Vorlage schlägt für die außerhalb der Klasse definierte Friend-Funktion fehl

Der folgende Code

<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);
}
</code>

kann mit der Fehlermeldung nicht kompiliert werden

foo.cpp: 18: 5: Fehler: Keine Übereinstimmung für 'operator==' im 'p == nullptr'
foo.cpp: 18: 5: note: kandidat ist:
foo.cpp: 14: 13: hinweis:template<class T> bool operator==(foo<T>, foo<T>)
foo.cpp: 14: 13: Anmerkung: Abzug / Ersetzung des Template-Arguments fehlgeschlagen:
foo.cpp: 18: 5: note: nicht übereinstimmende Typen 'foo<T>' und 'std::nullptr_t'

Wenn ich jedoch stattdessen die Definition in der Klasse verwende, funktioniert der Code wie erwartet.

Lass mich das sagenIch verstehe die Fehlermeldung: das Template-ArgumentT kann für den Typ von nicht abgeleitet werdennullptr (übrigens,decltype(*nullptr) kompiliert nicht). Darüber hinaus kann dies hier behoben werden, indem lediglich die Funktion innerhalb der Klasse definiert wird.

Aus Gründen der Einheitlichkeit (es gibt aber auch andere Freundfunktionen die ich habe)brauchen außerhalb der Klasse definieren) Ich möchte diese Funktion außerhalb der Klasse definieren.

Gibt es einen „Trick“, um die Funktion außerhalb der Klassendefinition arbeiten zu lassen?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage