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

时间:2019-03-21 16:25:49

标签: c++ language-lawyer

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


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

  

当函数调用(5.2.2)中的postfix-expression是不合格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)是后缀表达式。

然后将 postfix-expression 的语法类别定义为

  

后缀表达式:

     

主要表达式

     

postfix-expression [表达式]

     

postfix-expression [braced-init-list]

     

后缀表达式(expression-list opt)

     

简单类型说明符(expression-list opt)

     

typename-specifier(expression-list opt)

     

简单类型说明符braced-init-list

     

typename-specifier braced-init-list

     

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

     

postfix-expression->模板opt id-expression

     

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

     

postfix-expression->伪析构函数名称

     

后缀表达式++

     

后缀表达式-

     

dynamic_cast (表达式)

     

static_cast (表达式)

     

reinterpret_cast (表达式)

     

const_cast (表达式)

     

typeid(表达式)

     

typeid(type-id)

在这种情况下,只有 primary-expression 是相关的。定义为

  

主要表达式:

     

文字

     

     

(表达式)

     

id-expression

     

lambda表达式

在这种情况下,只有 id-expression 是相关的,并且定义为

  

id-expression:

     

不合格ID

     

qualified-id

因此f(f)是其中之一。如果(f)不是不合格ID(因为ADL被抑制),则它应该是 qualified-id 之一。但是它定义为

  

qualified-id:

     

:: opt嵌套名称说明符模板opt unqualified-id

     

::标识符

     

::操作员功能ID

     

::文字运算符ID

     

::模板ID

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


补充:

This answer(在this comment中给出)说

  

如本标准附录A中所述,post-fix expression形式的(expression)primary expression,但不是id-expression,因此不是{{ 1}}。这意味着与常规形式unqualified-id相比,在形式为(fun)(arg)的函数调用中可以防止依赖于参数的名称查找。

但这是正确的吗? expression 的语法类别定义为

  

表达式:

     

分配表达式

     

表达式,赋值表达式

附件A中的

。我认为fun(arg)中的f不是表达式之一。

1 个答案:

答案 0 :(得分:1)

(f)( 表达式 ),而不是 unqualified-id ,因此ADL不适用。带括号的 unqualified-id 不再是 unqualified-id 。在某些情况下,该标准表示“可能用括号括起来的” X等效于X。依赖于参数的查找不是其中一种情况。