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

C++ 在这种情况下,为什么不考虑参数相关查找?,c++,language-lawyer,C++,Language Lawyer,这个问题基于C++11标准(N3092) 3.4.2-1依赖于参数的名称查找 当函数调用(5.2.2)中的后缀表达式是非限定id时,可以搜索在常规非限定查找(3.4.1)过程中未考虑的其他名称空间,并且在这些名称空间中,可以找到不可见的名称空间范围友元函数声明(11.4)。对搜索的这些修改取决于参数的类型(对于模板参数,则取决于模板参数的命名空间)。[示例: -[结束示例] ,但我不明白为什么(f)(s)会抑制ADL(参数相关查找)这就是我想问的问题。 根据5.2.2-1函数调用 函数调用是一

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


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

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

-[结束示例]

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

根据5.2.2-1函数调用

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

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

然后将后缀表达式的语法类别定义为

后缀表达式:

初级表达

后缀表达式[表达式]

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

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

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

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

简单类型说明符大括号初始化列表

类型名说明符大括号初始化列表

后缀表达式。模板optid表达式

后缀表达式->模板选项id表达式

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

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

后缀表达式++

后缀表达式--

动态强制转换(表达式)

静态转换(表达式)

重新解释类型转换(表达式)

const_cast(表达式)

类型ID(表达式)

类型id(类型id)

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

主要表达式:

文字的

这个

(表达)

id表达式

lambda表达式

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

id表达式:

不合格id

合格id

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

合格id:

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

::标识符

::运算符函数id

::文本运算符id

::模板id

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


补编:

(在中给出)说

如本标准附录A所述,格式为
(表达式)
后期表达式是
主表达式
,但不是
id表达式
,因此也不是
不合格id
。这意味着,与传统的
fun(arg)
形式相比,在
(fun)(arg)
形式的函数调用中,可以防止参数相关的名称查找

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

表达方式:

赋值表达式

表达式,赋值表达式


在附录A中,我不认为
(f)
中的
f
是表达式的一种。

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

已回答。试着看看是否有更好的目标谢谢你的回答。你能看看我的补充资料吗?我认为
f
不属于表达式的语法范畴。@ynn
f
是一个表达式,因为它是赋值表达式,这是因为它是一个条件表达式,这是因为它是一个逻辑or表达式,等等。谢谢。在多次跳转之后,我最终返回到postfix表达式(属于
f
)。
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
}