C++ 友元函数

C++ 友元函数,c++,lookup,C++,Lookup,以下内容是什么意思(尤其是突出显示的部分)?为什么表达式“f(a)”被视为“强制转换表达式” C++03$3.4./3-“查找非限定名称 用作a的后缀表达式 函数调用如3.4.2所述。 [注:为了确定 (在解析过程中)表达式是否 是函数的后缀表达式 调用,通常的名称查找规则 适用。3.4.2中的规则没有 对句法解释的影响 指表达式。例如 表达式f(a)是一个与int(a)等价的强制转换表达式。由于该表达式不是函数调用,因此依赖于参数的名称查找(3.4.2)不适用,并且找不到友元函数f。]” 有什

以下内容是什么意思(尤其是突出显示的部分)?为什么表达式“f(a)”被视为“强制转换表达式”

C++03$3.4./3-“查找非限定名称 用作a的后缀表达式 函数调用如3.4.2所述。 [注:为了确定 (在解析过程中)表达式是否 是函数的后缀表达式 调用,通常的名称查找规则 适用。3.4.2中的规则没有 对句法解释的影响 指表达式。例如

表达式f(a)是一个与int(a)等价的强制转换表达式。由于该表达式不是函数调用,因此依赖于参数的名称查找(3.4.2)不适用,并且找不到友元函数f。]”


有什么想法吗?

这意味着解析器首先确定括号前的表达式是id表达式还是后缀表达式。在这种情况下,它会看到
f
,最近定义的
f
typedef int f
——因此它得出结论,表达式被解释为
int(a)
,并且不执行Koenig查找

让我们来看看这段代码(您可以在线试用:)

如果您声明了一个从
g
可见的(不相关的)函数
f
,它将被解释为一个函数调用,Koenig lookup将找到正确的重载(请参见第
#2
行)

f
的好友声明不应在此处应用,因为

11.4/1:。。。朋友的名字不在类的范围内

然而,让我不安的是,取消注释
#1
也会使编译器(在本例中是gcc)调用
x::f(A&)
。不知道为什么。[在Comeau Online compiler中,它按预期工作(例如,
#1
不影响行
#3
)。不过,最新的测试版在编译此代码时存在问题。]

PS:正如litb所指出的,C++0x中的规则有些不同:

3.4.2/3:

设X为生成的查找集 不合格查找(3.4.1)并让Y为 由参数生成的查找集 相关查找(定义如下)。 如果X包含

  • 类成员的声明,或
  • 不是using声明的块作用域函数声明,或
  • 既不是函数也不是函数模板的声明
那么Y是空的。否则Y就是 在中找到的声明集 与

粗体项将使编译器只考虑<代码>无效>()>代码>,并且由于参数太多而失败。


它似乎是由的解析引入的。

取消注释#2将根据C++0x规则禁用koenig查找(一些编译器甚至在C++03模式下也使用这些规则)。因此,它将作为函数调用编译,但作为对本地声明函数的调用编译,并将导致错误。@Johannes Schaub-litb:很想知道为什么在名称查找过程中找不到friend函数,即使它在类的词法范围内。@Chubsdad:那是因为它不在类的范围内。@Chubsdad“在类的词法范围内”是一个措辞糟糕的规则。它只是意味着函数可以找到具有非限定名称的类成员。它并不意味着/它并不意味着函数名称在类的范围内。
typedef int f;
struct A {
friend void f(A &);
operator int();
void g(A a) {
f(a);
}
};
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
    }
  };
}