为什么在这种情况下不考虑依赖于参数的查找?

Why in this case does argument-dependent lookup not considered?

本文关键字:查找 参数 依赖于 这种情况下 不考虑 为什么      更新时间:2023-10-16

此问题基于 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 ID 表达式

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

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

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

后缀表达式 ++

后缀表达式 --

dynamic_cast<类型 ID=">( 表达式 )

static_cast<类型 ID=">( 表达式 )

reinterpret_cast<类型 ID=">( 表达式 )

const_cast<类型 ID=">( 表达式 )

类型标识 ( 表达式 )

类型标识 ( 类型标识 )

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

主要表达式:

字面

( 表达式 )

身份表达式

λ表达式

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

id-表达式:

非限定标识

限定标识

所以f(f)就是其中之一。如果(f)不是非限定 id(因为 ADL 被抑制),则它应该是限定 id之一。但它被定义为

限定标识:

:: 选择嵌套名称说明符模板 选择非限定 ID

::标识符

:: 运算符函数 ID

:: 文字运算符 ID

:: 模板标识

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

<小时 />

补充:

这个答案(在此评论中给出)说

正如标准附录A所详述的,(expression)形式的post-fix expressionprimary expression,但不是id-expression,因此不是unqualified-id。这意味着与传统形式fun(arg)相比,在形式(fun)(arg)的函数调用中阻止了与参数相关的名称查找。

但这是正确的吗?表达式的语法类别定义为

表达:

赋值表达式

表达式 , 赋值表达式

见附件A。我不认为f(f)是一种表达

(f)(表达式),而不是非限定 id,因此 ADL 不适用。带括号的非限定 id不再是非限定 id。在某些情况下,标准说"可能括起来的"X等同于X.依赖于参数的查找不是这些情况之一。