我试图在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
答案 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) {
...
}