这是关于涉及默认参数推导/替换的测试用例。测试用例可以概括为:
template <class T, class = typename T::I>h(T){}
template <class T, class = typename T::I>j(T){}
class A
{
typedef int I;
friend void h<A>(A);
};
int main()
{
A a;
h(a);
j(a);
}
gcc-4.8.1 对函数 j 抛出错误,因为它没有被声明为友元,也不是类 A 私有的,因此违反了私有成员 I 的访问规则(这是有效的)。gcc 不会为函数 h 抛出错误,因为它已被声明为类 A 的朋友,因此可以访问私有成员 I。
Clang 对这两个函数都抛出错误。函数 j 的错误(未声明的朋友是有效的并且如预期的那样),但即使对于朋友函数 h 也会引发错误(错误:默认 arg 的推导失败,因为我是 A 类的私有成员)。这违反了朋友功能的可访问性。
我检查了代码路径。虽然 clang 能够推断出默认参数,但它会在进行任何替换之前检查访问规则,并给出错误。有人可以就如何解决这个问题提供指导吗?