c++ - 对于在类外定义的友元函数,模板上的隐式转换查找失败

标签 c++ templates c++11

下面的代码

#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/

相关文章:

c++ - 从子构造函数(模板)访问父成员

c++ - 如何删除可变参数模板的最后一个参数

c++ - 如何在 Qt 中编写自定义弹出窗口?

templates - 用于创建类似于 StackOverflow 的分页 UI/链接的 Knockout 模板

Java 表达式语言 : Interpolation?

c++ - 给定结构类型返回某个字符缓冲区的绝对最快(并且希望优雅)的方法

c++ - move 的 vector 总是空的吗?

c++ - 关于 C++ 类中的转换

c++ - 为什么我的代码在 SPOJ 上给出了错误的答案?

c++ - 如何将 OS X 风格添加到 Qt 应用程序