代码之家  ›  专栏  ›  技术社区  ›  ynn

在这种情况下,为什么不考虑参数相关的查找?

  •  0
  • ynn  · 技术社区  · 7 年前

    这个问题基于C++11标准(N3092)。


    3.4.2-1 依赖于参数的名称查找

    当函数调用(5.2.2)中的后缀表达式是非限定id时 ,可以搜索在通常的非限定查找(3.4.1)过程中未考虑的其他名称空间,并且在这些名称空间中,可以找到不可见的名称空间范围友元函数声明(11.4)。对搜索的这些修改取决于参数的类型(对于模板参数,则取决于模板参数的名称空间)。[示例:

    namespace N {
        struct S { };
        void f(S);
    }
    
    void g() {
        N::S s;
        f(s); // OK: calls N::f
        (f)(s); // error: N::f not considered; parentheses
                // prevent argument-dependent lookup
    }
    

    –结束示例]

    ,但我不明白为什么 (f)(s) 抑制ADL(参数相关查找)。 这就是我想问的。

    根据5.2.2-1 函数调用 ,

    函数调用是一个后缀表达式,后跟括号,括号中可能包含空的、逗号分隔的表达式列表,这些表达式构成函数的参数。

    所以在这种情况下, f (f) 是后缀表达式。

    然后是 后缀表达式 定义为

    后缀表达式:

    主要表达

    后缀表达式[表达式]

    后缀表达式[大括号初始化列表]

    后缀表达式(表达式列表选项)

    简单类型说明符(表达式列表opt)

    typename说明符(表达式列表选项)

    简单类型说明符加括号的init list

    类型名说明符括号内的初始列表

    后缀表达式。模板opt-id表达式

    后缀表达式->模板opt-id表达式

    后缀表达式。伪析构函数名

    后缀表达式->伪析构函数名

    后缀表达式++

    后缀表达式--

    动态演员阵容<类型id>(表达)

    静态_cast<类型id>(表达)

    重新解释演员阵容<类型id>(表达)

    const_cast<类型id>(表达)

    typeid(表达式)

    类型id(类型id)

    在这种情况下,只有 主要表达 这是相关的。它被定义为

    主要表达:

    字面意义的

    (表达)

    id表达式

    lambda表达式

    在这种情况下,只有 id表达式 是相关的,定义为

    id表达式:

    不合格id

    合格身份证

    所以 F (f) 是其中之一。如果 (f) 不是非限定id(因为ADL被抑制),它应该是 合格身份证 .但它的定义是

    合格身份证:

    ::opt嵌套名称说明符模板opt非限定id

    ::标识符

    ::操作员函数id

    文字运算符id

    ::模板id

    我想 (f) 不是其中之一。如果是,为什么 (f) (s) 抑制ADL?


    补编:

    This answer (这是在 this comment )说

    如本标准附录A所述 post-fix expression 形式 (expression) 是一个 primary expression ,但不是 id-expression ,因此不是 unqualified-id 。这意味着在窗体的函数调用中禁止依赖于参数的名称查找 (fun)(arg) 与传统形式相比 fun(arg) .

    但这是正确的吗?语法范畴 表示 定义为

    表达方式:

    赋值表达式

    表达式,赋值表达式

    在附件A中,我不认为 F 在里面 (f) 是其中之一 表示 .

    1 回复  |  直到 6 年前
        1
  •  1
  •   Brian Bi    7 年前

    (f) ( 表示 ) 不合格id 因此ADL不适用。括号中的 不合格id 不再是一个 不合格id .在某些情况下,标准规定“可能带括号”的X等同于X。依赖于参数的查找不属于此类情况。