class with friend 而不是 forward declaration,: 哪个编译器是正确的

class with friend rather than forward declaration,: which compiler is correct

我有这个简单的 C++ 程序:

#include <iostream>

struct obj {
  friend int f(int);

  void m(int x) { std::cout << "f(" << x << ") = " << f(x) << std::endl; }
};

int main() {
  obj o;
  o.m(21);
}


int f(int x) {
  return 2*x;
}

如果我用 GNU C++ 编译器 g++ 编译,我得到错误 prog.cpp:7:55: error: 'f' was not declared in this范围

但是,如果我用 cl(和 /W4)编译它,它会编译并执行得很好。

我不确定哪个编译器是正确的。

来自 friend declaration 上的 cppreference:

A name first declared in a friend declaration within class or class template X becomes a member of the innermost enclosing namespace of X, but is not visible for lookup (except argument-dependent lookup that considers X) unless a matching declaration at the namespace scope is provided

提供了全局范围内的匹配声明,但仅在 obj::m() 的定义之后。我认为此时拒绝对 f 的调用是正确的。你可以看到效果,例如这与 gccclang,

一起编译
int f(int);

class obj { /* as before... */ };

还有这个:

struct obj {
  friend int f(int);

  void m(int x); 
};

int f(int);

void obj::m(int x) { std::cout << "f(" << x << ") = " << f(x) << std::endl; }