类(模板)成员函数体内部的ADL查找
ADL lookup inside a class (template) member function body
struct B {};
struct C : B {};
void f(B){} // worse match than A::f<C>
struct A {
template<class T>
void f(T v) {
f(v); // #1
}
};
int main()
{
A{}.f(C{});
}
激活#1
行中的ADL查找与一样简单
{
using ::f;
f(v);
}
我认为使代码在没有using
指令的情况下失败的规则是:
[basic.lookup.argdep]/3设X为非限定查找生成的查找集,设Y为由参数相关查找生成的查找集(定义为如下)。如果X包含
- (3.1)类成员的声明,或
- (3.2)不是using声明的块作用域函数声明,或者
- (3.3)既不是函数也不是函数模板的声明
则Y为空。[…]
因此,由于通过非ADL查找找到的对f
的调用将找到作为类成员的A::f
,因此通过ADL查找发现的重载将被丢弃。
哪个C++规则允许用using
声明忽略3.1中的限制,以编译上述代码?
我想我完全误解了必须应用规则[basic.lookup.argdep]/3的上下文,或者我对名称查找过程的理解可能有一个更大的隐藏漏洞。
关于不合格名称查找的第一段:
在〔basic.lookup.uqual〕中列出的所有情况下,作用域都是按每个中列出的顺序搜索声明各自类别;一旦声明为名称找到。
特别是
对于类
X
的成员,在成员函数体中使用的名称[…]如下成员的声明符id,应在以下方式:
在使用它的块中或在封闭中使用之前块([stmt.block])或
应为
X
类成员或成员X
([class.member.lookup])的基类,或者。。。
对名称的本地(re)声明进行优先级排序,并隐藏所有外部声明。
相关文章:
- 将函数类成员映射到类本身内部
- Boost Spirit,获取迭代器内部语义动作
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 内联函数中具有内部链接的全局变量
- 在函数内部的声明中初始化数组,并在外部使用它
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 有没有可能有一个只有ADL才能找到的非好友功能
- 卷曲bracers内部结构的声明
- 从函数角度看ID到文件路径的内部与外部映射
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 如何在pugixml中获取节点的内部XML
- 使用C链接在函数内部创建C++模板
- 指针没有更新它在void函数内部指向的值
- 方法内部但循环仍得到预期的不合格id错误C++
- C++:具有内部链接的正向声明常量
- SDL_PollEvent() 无法捕获类函数内部SDL_QUIT?
- 函数中的 c++ using 语句,后跟函数名称(对于 ADL?
- libcurl 和 DNS ttl 中的内部连接管理
- 如何修改 lambda 内部字符串的向量
- 类(模板)成员函数体内部的ADL查找