这是关于涉及默认参数的测试用例 扣/替换。测试用例可以概括为:
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的错误,因为它没有被声明为friend,也没有对A类私有,因此违反了私有成员I的访问规则(这是有效的)。 gcc不会为函数h抛出错误,因为它已被声明为A类的朋友,因此可以访问私有成员I.
Clang抛出两个函数的错误。函数j的错误(未声明的朋友是有效的并且正如预期的那样),但即使对于朋友函数h也会抛出错误(错误:由于我是A类的私有成员,因此默认arg的推断失败)。这违反了朋友功能的可访问性。
我检查了代码路径。虽然clang能够推断出默认参数,但它会在进行任何替换之前检查访问规则,并给出错误。有人可以就如何解决这个问题提供指导吗?
答案 0 :(得分:1)
您忘记了模板函数的返回类型。
这应该可以解决问题:
template <class T, class = typename T::I> void h(T){}
template <class T, class = typename T::I> void j(T){}
修正上述错误后,我仍然遇到错误,因为
完全可编辑的问题在这里:
#include <iostream>
// Type your code here, or load an example.
template <class T, class = typename T::I> void h(T t){std::cout<<t.a<<std::endl;}
template <class T, class = typename T::I> void j(T t){std::cout<<t.a<<std::endl;}
class A
{
friend void h<A,int>(A);
friend void j<A,int>(A);
public :
typedef int I;
private :
int a;
};
int main()
{
A a;
h(a);
j(a);
}