指向全局运算符的函数指针在 VC++ 上编译,而 clang 给出错误

Function pointer to global operator compiles on VC++ while clang gives an error

本文关键字:编译 clang 错误 出错 VC++ 运算符 全局 函数 指针      更新时间:2023-10-16

我正在尝试获取以下代码以在 clang 上编译,但它失败并出现以下错误:

error: no member named 'operator<' in the global namespace

我尝试使用/Za 编译视觉工作室代码以切换到标准一致性,但它似乎仍然接受它。请开导我。

struct A
{
  int m_test;
  A(int test)
    : m_test(test)
  {
  }
  friend bool operator<(A left, A right);
};
int main()
{
  typedef bool(*TCompare)(A,A);
  TCompare compare = &::operator<;
  compare(9,7);
}

VC++ 输出:https://godbolt.org/g/LAz56n

叮当输出:https://godbolt.org/g/zC2InO

Clang 是正确的。对于示例代码,友元声明引入的名称operator<确实成为全局命名空间的成员,但名称查找不可见。它只能通过 ADL 找到,但 ADL 仅适用于函数调用表达式,而&::operator<则不适用于。

非本地类X中的友元声明引入的名称 成为X最内层封闭命名空间的成员,但它们确实如此 对查找不可见(既不合格也不合格) 除非在命名空间范围内提供了匹配的声明,否则 在类定义之前或之后。这样的名称可以通过 ADL 同时考虑命名空间和类。

要修复它,您必须在全局命名空间范围内添加一个匹配的声明。

struct A
{
  int m_test;
  A(int test)
    : m_test(test)
  {
  }
  friend bool operator<(A left, A right);
};
// add a matching declaration at namespace scope
bool operator<(A left, A right);
int main()
{
  typedef bool(*TCompare)(A,A);
  TCompare compare = &::operator<;
  compare(9,7);
}
bool operator<(A left, A right) { 
    ... 
}
这是一个

VC++错误。代码无效。

友元声明不会将声明的名称引入全局命名空间。您仍然需要在类外部声明它。