c++ - : bug or feature? 类内和类外定义的 friend 区别

标签 c++ language-lawyer friend-function

<分区>

考虑:

struct Y {
  Y(float f) : f(f) {}
  float f;
};

struct X {
  X(Y y) : i(y.f) {}
  int i;
  friend bool operator==(X x1, X x2) {
    return x1.i == x2.i;
  }
};

int main()
{
    return Y(1) == Y(2); // ERROR
}

这会导致 MSVC 上出现以下错误,Clang 上也会出现类似错误:

'==': candidate function(s) not accessible
could be the friend function at '..\main.cpp(11)' : '=='  [may be found via argument-dependent lookup]

如果我将友元函数的定义移出类:

struct X {
    X(Y y) : i(y.f) {}
    int i;
    friend bool operator==(X x1, X x2);
};

inline bool operator==(X x1, X x2)
{
    return x1.i == x2.i;
}

上面 main() 中的表达式可以正常编译。

这是标准规定的还是错误?如果强制执行:为什么?

最佳答案

这是 C++ 的怪癖。

[C++14: 11.3/7]: [..] A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).

这意味着如果您从成员函数 but not otherwise 中进行运算符调用,运算符调用将起作用。 .即使它不是成员(member)。

依赖于参数的查找是关于调用它的唯一其他方法,但这对您在这里没有用,因为两个参数都是 X s,不是 Y

您的解决方法是最好的解决方法,并且可以避免这种困惑(如您所见)。

关于c++ - : bug or feature? 类内和类外定义的 friend 区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31183484/

相关文章:

c++ - 为什么实例化函数模板可以(隐式)使用未声明的符号?

c++ - 将命名空间声明为类的 friend

c++ 与成员变量同名的内联友元函数

c++ - 在 Linux 上交叉编译 Windows 应用程序时如何链接到 Winsock?

c++ - 从 MSVC 19.29 (VS16.11) 开始,条件运算符表达式出现问题 C2445

c++ - 验证用户输入为坐标(A1…)

c++ - 使用不完整类型的函数模板实例化

c++ - 为什么LNK1120 & LNK2019在模板和友元函数的情况下出现

c++ - 为可维护性和封装性构建 C++ 类层次结构

c++ - boost::format 仅在 Windows 下异常