运算符在 class 中定义为 friend 的奇怪行为

Weird behavior with operator defined as friend inside class

我不明白下面这段代码是怎么回事:

struct A { };

struct B {
  B() { }
  B(const A&) { }

  friend B operator*(const B&, const B&)
  {
    return B();
  }
};

int main()
{
  B x = A() * A();

  return 0;
}

当我编译(同时使用 clang 和 gcc 4.9.2)时,我在 "B x = A() * A()" 行收到一条错误消息; clang 说 "invalid operands to binary expression".

如果我从 class 内部获取 operator* 定义,一切都 100% 正常!

struct A { };

struct B {
  B() { }
  B(const A&) { }

  friend B operator*(const B&, const B&);
};

B operator*(const B&, const B&)
{
  return B();
}

int main()
{
  B x = A() * A();

  return 0;
}

这是怎么回事?

由于operator*()在函数内部定义为友元,所以只能通过ADL查找,不能正常不合格查找。这种类型的查找要求参数是精确类型,而不是可隐式转换的类型。这意味着即使 A 可以转换为 B.

也找不到运算符

当你在class外声明函数时,可以通过正常的非限定查找规则找到它。