在类(模板)成员函数体内进行ADL查找

时间:2017-10-28 16:33:15

标签: c++ language-lawyer c++17 argument-dependent-lookup class-members

@Recover

在行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{}); } 中激活ADL查找就像

一样简单
#1

我认为在没有{ using ::f; f(v); } 指令的情况下使代码失败的规则是:

  

[basic.lookup.argdep]/3设X是非限定查找生成的查找集,让Y为   由参数依赖查找生成的查找集(定义为   如下图)。如果X包含

     
      
  • (3.1)集体成员的声明,或
  •   
  • (3.2)不是使用声明的块范围函数声明,或
  •   
  • (3.3)既不是功能也不是功能模板的声明
  •   
     

然后Y为空。 [...]

因此,由于非ADL查找找到的using调用将找到f,这是一个类成员,ADL-lookup发现的重载将被丢弃。

哪个C ++规则允许使用A::f声明忽略3.1中的限制,以使上述代码编译?

我认为我完全误解了必须应用规则 [basic.lookup.argdep] / 3 的上下文,或者我对这个名字的理解有一个更大更隐蔽的漏洞查找过程。

1 个答案:

答案 0 :(得分:5)

关于非限定名称查找的

First paragraph

  

在[basic.lookup.unqual]中列出的所有情况中,范围都是   按照每个中列出的顺序搜索声明   各自的类别;名称查找在声明后立即结束   找到了这个名字。

In particular

  

对于类class ObjectPostSerializer(serializers.ModelSerializer): def __init__(self, *args, **kwargs): super(ObjectPostSerializer, self).__init__(*args, **kwargs) for key in self.fields: self.fields['field3'].required = False class Meta: model=Object field3 = model.field2 fields = ('__all__') 的成员,在成员函数体[...]中使用的名称如下   会员的声明者身份,应在其中一个声明   以下方式:

     
      
  • 在使用它之前或在封闭中使用之前   阻止([stmt.block])或

  •   
  • 应为班级X的成员或成为会员   基类X[class.member.lookup])或......

  •   

对名称的本地(重新)声明进行优先排序,并隐藏所有外在声明。