带有朋友而不是前向声明的类,:哪个编译器是正确的[重复]

Posted

技术标签:

【中文标题】带有朋友而不是前向声明的类,:哪个编译器是正确的[重复]【英文标题】:class with friend rather than forward declaration,: which compiler is correct [duplicate] 【发布时间】:2019-07-23 12:24:51 【问题描述】:

我有这个简单的 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' is not declared in this scope

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

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

【问题讨论】:

【参考方案1】:

来自friend declaration上的cppreference:

在类或类模板 X 中的友元声明中首先声明的名称成为 X 的最内层封闭命名空间的成员,但对于查找不可见(除了考虑 X 的参数相关查找),除非在提供了命名空间范围

提供了一个全局范围的匹配声明,但仅在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; 

【讨论】:

friend int f(obj const&amp;, int); 所以ADL可以通过添加第一个参数来工作(即使它是一个虚拟参数)。

以上是关于带有朋友而不是前向声明的类,:哪个编译器是正确的[重复]的主要内容,如果未能解决你的问题,请参考以下文章

idjl(Sun IDL 编译器)是不是支持前向声明?

重构 C++ 代码以使用前向声明

使用前向声明时如何修复“字段类型不完整”错误

20210421-C++的前向声明

带有前向声明的循环包含和继承导致 C2504 基类未定义

如何正确制作带有模板数组的类对象?