以下是什么意思(特别是突出显示的部分)?为什么表达式'f(a)'被视为'演员表达'?
C ++ 03 $ 3.4。/ 3-“查找不合格的名称 用作a的后缀表达式 函数调用在3.4.2中描述。 [注:用于确定的目的 (在解析期间)是否是表达式 是函数的后缀表达式 调用,通常的名称查找规则 应用。 3.4.2中的规则没有 对句法解释的影响 一个表达。例如,
typedef int f;
struct A {
friend void f(A &);
operator int();
void g(A a) {
f(a);
}
};
表达式f(a)是等效于int(a)的强制转换表达式。因为表达式不是函数调用,所以参数依赖的名称查找(3.4.2)不适用,并且找不到友元函数f。 ]“
有什么想法吗?
答案 0 :(得分:1)
这意味着解析器首先确定括号前的表达式是 id 还是 postfix-expression 。在这种情况下,它会看到f
,并且最接近的f
定义为typedef int f
- 因此它总结表达式被解释为int(a)
并且不执行Koenig查找。
让我们拥有这段代码(您可以在线试用:http://ideone.com/clone/eRKvP)
typedef int f;
namespace x {
struct A {
friend void f(A &);
//friend void f(); // # 1
operator int();
void g(A a) {
//void f(); // # 2
(void)f(a); // # 3
}
};
}
如果您从f
声明了一个(无关的)函数g
,它将被解释为函数调用,Koenig查找将找到正确的重载(请参阅第#2
行)。
f
的朋友声明不应该适用于此,因为
11.4 / 1:......朋友的名字不属于班级范围,
然而,让我感到不安的是,取消注释#1
会使编译器(在本例中为gcc)也调用x::f(A&)
。不知道为什么会这样。 [在Comeau Online编译器中,它按预期工作(例如。#1
不影响行#3
)。但是,最新的测试版在编译此代码时遇到了问题。]
PS:如litb所述,C ++ 0x中的规则略有不同:
3.4.2 / 3:
设X是由...生成的查找集 unquali fi ed lookup(3.4.1)并让Y成为 参数生成的查找集 从属查找(定义如下)。 如果X包含
- 类成员的声明,或
- 块范围函数声明,它不是using声明或
- 既不是函数也不是函数模板的声明
然后Y为空。否则Y就是 发现的一组声明 与
关联的名称空间
粗体项将使编译器仅考虑void f()
并且因参数太多而失败。
似乎是由issue 218的决议引入的。