我有一个类,它在类头中定义了一个friend函数。当我使用声明这个朋友函数时,它在MSVC2017中起作用,但在GCC 8.2或Clang7.0中不起作用。谁是对的?下面是godbolt链接(https://godbolt.org/z/_7MVlh),代码如下:
namespace vec {
class Vec {
    friend Vec vec_max(const Vec& a, const Vec& b) { return a; }
};
}
void test() {
    using vec::vec_max;
}GCC在using声明中给出了错误:“错误:命名空间‘vec’中没有名为'vec_max‘的成员”。Clang也给出了类似的信息。MSVC按照预期对其进行了编译。
根据我的理解,vec_max应该驻留在vec名称空间中,MSVC应该是正确的。但标准中可能存在一些微妙的文字,使得对gcc和碰的更严格的解释是正确的(尽管不那么直观)。
发布于 2018-11-21 18:16:47
MSVC在这里是错误的。如果友元函数是在类定义内内联定义的,而不是在外部声明的,则不应该通过常规的名称查找找到它,只有依赖于参数的查找才能找到它。
报价C++17 (n4659):
14.3 class.friend
6当且仅当类是非本地类(12.4)、函数名未限定且函数具有命名空间作用域时,才能在类的友元声明中定义函数。..。
7这样的函数隐式地是内联函数(10.1.6)。在类中定义的friend函数在定义它的类的(词法)范围内。在类外部定义的友元函数不是(6.4.1)。
和6.4.2/4 basic.lookup.argdep
考虑关联的命名空间时,查找与将关联的命名空间用作限定符(6.4.3.2)时执行的查找相同,不同之处在于:
https://stackoverflow.com/questions/53409706
复制相似问题