次のコード
#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);
}
エラーメッセージでコンパイルに失敗します
foo.cpp:18:5:エラー:''の''に一致しませんfoo.cpp
operator==
: 18:5:注:候補は: foo.cpp:14:13:注: foo.cpp:14:13:注:テンプレート引数の推定/置換に失敗しました: foo.cpp:18:5:注:タイプ' 'と' ' の不一致p == nullptr
template<class T> bool operator==(foo<T>, foo<T>)
foo<T>
std::nullptr_t
ただし、代わりにクラス内の定義を使用すると、コードは期待どおりに機能します。
エラーメッセージを理解しているとしましょう。テンプレート引数T
は、のタイプに対して推測できませんnullptr
(ちなみに、decltype(*nullptr)
コンパイルされません)。さらに、これはクラス内で関数を定義するだけでここで修正できます。
ただし、統一性の理由から(外部で定義する必要のある他のフレンド関数があります)、この関数をクラスの外部で定義したいと思います。
関数のクラス外定義を機能させるための「トリック」はありますか?