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

时间:2017-02-02 08:55:44

标签: c++ visual-c++ language-lawyer friend clang++

我试图在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

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:5)

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

  

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

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

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