uj2*_*uj2 6 c++ templates friend-function argument-dependent-lookup
考虑以下代码:
template <int N>
struct X
{
friend void f(X *) {}
};
int main()
{
f((X<0> *)0); // Error?
}
Run Code Online (Sandbox Code Playgroud)
编译器似乎非常不同意.(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?
}
Run Code Online (Sandbox Code Playgroud)
这里的关键问题是注入的可行功能是否X<1>应该在ADL期间可见X<0>?它们是否相关?上面提到的所有编译器都接受此代码,但Comeau仅在宽松模式下接受它.不确定标准对此有何看法.
你对此有何看法?
该标准说14.7.1/4
如果类类型在需要完全定义的对象类型的上下文中使用,或者类类型的完整性影响程序的语义,则类模板特化会被隐式实例化;特别是,如果类型为类模板特化的表达式涉及重载解析、指针转换、指向成员的指针转换,则隐式实例化类模板特化(3.2);
请注意,Vandervoorde在这里做了一份问题报告,委员会发现
标准已经指定这会创建一个实例化点。
对于第二种情况 - 您需要考虑参数的关联类和名称空间f(X<0>*)。这些是,因为这是一个指向类模板专门化的指针(请注意,下面的“template-id”不太正确 - C++0x 更正了它以使用正确的术语),也是一个指向类的指针(这种令人困惑的分割在 C++0x 中也得到了纠正 - 它在一个要点中列出了这两种情况)。
如果 T 是 template-id,则其关联的命名空间和类是定义模板的命名空间;[...很多噪音...]
如果 T 是类类型(包括联合),则其关联的类是: 类本身;它所属的类别(如果有);及其直接和间接基类。其关联的命名空间是定义其关联的类的命名空间。
总而言之,我们有关联的类X<0>,关联的命名空间是全局命名空间。现在可见的友元函数是
- 在关联类中声明的任何名称空间范围的友元函数在其各自的名称空间内都是可见的,即使它们在普通查找期间不可见
没有声明友元函数,X<0>因此在查看全局命名空间时,友元函数声明不可见。请注意,这X<0>是与 完全不同的类类型X<1>。您在那里执行的隐式实例化对此调用X<1>没有影响 - 它只是将一个不可见的名称添加到引用 class 的友元函数的全局命名空间中X<1>。
| 归档时间: |
|
| 查看次数: |
1194 次 |
| 最近记录: |