考虑这段代码:
template <int N>
struct X
{
friend void f(X *) {}
};
int main()
{
f((X<0> *)0); // Error?
}
编译器似乎非常不同意。(MSVC08/10 说不,GCC<4.5 说是,但是 4.5 说不,sun 5.1 说是,intel 11.1 也说是,但是 comeau 说不(两者都是 EDG))。
根据“C++ 模板 - 完整指南”:
...假设涉及在关联类中查找朋友的调用实际上会导致该类被实例化...尽管这显然是编写 C++ 标准的人想要的,但标准中并未明确说明。
我在标准中找不到相关部分。有什么参考吗?
考虑这种变化:
template <int N>
struct X
{
template <int M>
friend void f(X<M> *) {}
};
template <>
struct X<0>
{
};
int main()
{
X<1>();
f((X<0> *)0); // Error?
}
这里的关键问题是在 ADL 期间注入的可行函数是否X<1>
应该可见X<0>
?它们有关联吗?上面提到的所有编译器都接受这个代码,除了 Comeau,它只在宽松模式下接受它。也不确定标准对此有何规定。
你对此有何看法?