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

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

我试图让以下代码在 clang 上编译,但它失败并出现以下错误:

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

我尝试用 /Za 编译 visual studio 代码以切换到标准一致性,但它似乎仍然接受它。请赐教。

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

Clang 输出:https://godbolt.org/g/zC2InO

这是一个 VC++ 错误。代码无效。

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

之外声明它

Clang 是正确的。对于您的示例代码,名称 operator<friend declarations does become the member of the global namespace, but it's not visible to name lookup. It can only be found by ADL 引入,但 ADL 仅适用于 function-call 表达式,而 &::operator< 不适用于

Names introduced by friend declarations within a non-local class X become members of the innermost enclosing namespace of X, but they do not become visible to lookup (neither unqualified nor qualified) unless a matching declaration is provided at namespace scope, either before or after the class definition. Such name may be found through ADL which considers both namespaces and classes.

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

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) { 
    ... 
}