下面的代码
#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: 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
'
但是,如果我改用类内部的定义,代码将按预期工作。
让我说我理解错误信息:模板参数T
不能推导出 nullptr
的类型(顺便说一句,decltype(*nullptr)
无法编译)。此外,这可以通过在类中定义函数来解决。
但是,出于统一性的原因(我需要在外部定义其他友元函数)我想在类外部定义此函数。
是否存在使函数的类外部定义起作用的“技巧”?
最佳答案
三种可能的选择
- 声明并定义一个类型为 rhs 的新友元函数为
std::nullptt_t
前任
inline bool operator ==(foo<T> lhs, std::nullptr_t rhs) { return true; }
- 或者当变量与
nullptr
等同时,明确说明nullptr
的类型
前任
assert(p == foo<int>(nullptr));
- 声明并定义一个类型为rhs的新友元函数为
void *
前任
inline bool operator ==(foo<T> lhs, void *rhs) {
if (rhs == nullptr)
return true;
else
return false;
}
关于c++ - 对于在类外定义的友元函数,模板上的隐式转换查找失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10375626/