请考虑以下事项:
var size = String.Join("", groupedByColorCode.Select(bcc => bcc.Size));
在第一种情况下,案例成功 - 我们考虑namespace N {
struct A { };
struct B {
B() { }
B(A const&) { }
friend void f(B const& ) { }
};
}
int main() {
f(N::B{}); // ok
f(N::A{}); // error
}
的关联命名空间并找到N::B
。大。
第二种情况失败了。为什么?根据{{3}}:
如果非本地类中的
N::f(B const&)
声明首先声明了类,函数,类模板或函数模板,则该友元是最内层封闭命名空间的成员。 [...]如果朋友的功能或功能模板 调用时,可以通过名称查找找到其名称,该名称查找考虑名称空间中的函数和与函数参数类型相关联的类(3.4.2)。
friend
的关联命名空间是N::A
,其中N
是其成员,为什么查找找不到它?
答案 0 :(得分:8)
这是因为f
未在关联类中声明。当参数的类型为B
时,B
是关联的类,但当参数的类型为A
时,{{1}}不是。
我引自[basic.lookup.argdep] / 4,强调我的:
在考虑关联的命名空间时,查找与执行时的查找相同 关联命名空间用作限定符(3.4.3.2),但以下情况除外:
- 忽略相关命名空间中的任何using-directive。
- 在关联类中声明的任何命名空间范围的朋友函数或朋友函数模板都是 即使它们在普通查找期间不可见(11.3),也可以在各自的命名空间中看到。
- 忽略除(可能重载的)函数和函数模板之外的所有名称。