gpt4 book ai didi

C++ 17 友元函数声明和内联命名空间

转载 作者:行者123 更新时间:2023-12-02 10:07:39 27 4
gpt4 key购买 nike

考虑以下程序

#include <iostream>

namespace N1
{
inline namespace N2
{
class A
{
public:
friend void f( const A & );
private:
int x = 10;
};

//void f( const A & );
}

void N2::f( const A &a ) { std::cout << a.x << '\n'; }
}

int main()
{
using namespace N1;

A a;

f( a );
}

根据 C++ 17 标准(10.3.1.2 命名空间成员定义)

3 If a friend declaration in a non-local class first declares a class, function, class template or function template97 the friend is a member of the innermost enclosing namespace. The friend declaration does not by itself make the name visible to unqualified lookup (6.4.1) or qualified lookup (6.4.3).



所以友元函数的名字在命名空间 N2 中是不可见的。所以它也应该在命名空间 N1 中不可见。

然而,代码在编译和执行时没有警告 叮当头 10.0.0 .

编译器 gcc HEAD 10.0.0 20191 发出警告
prog.cc:18:10: warning: 'void N1::N2::f(const N1::N2::A&)' has not been declared within 'N1::N2'
18 | void N2::f( const A &a ) { std::cout << a.x << '\n'; }
| ^~
prog.cc:10:25: note: only here as a 'friend'
10 | friend void f( const A & );
| ^

但运行程序并输出正确的结果。

Visual C++ 2019 也成功编译了代码,没有警告,程序输出了预期的结果。

是不是三个编译器的bug是因为名字 f是不可见的所以友元函数的定义 f在封闭的命名空间中是不正确的?

最佳答案

正如我在评论中提到的,f 的函数体和参数并不真正相关,因为问题仅与 N2::f 的名称查找有关。 .删除它们后,命名空间N2 是否也无关紧要。是 inline或不。在任何一种情况下,所有编译器的行为方式都相同。

GCC 发出警告,但给出了一个硬错误 -pedantic-errors关于N2::f的定义. MSVC 和 Clang 总是接受没有诊断的代码。

我认为你是对的,按照措辞 N2::f在函数定义声明符中应该通过限定名查找规则来查找,应该找不到friend声明没有 f 的介入声明在 N2的范围,不使用限定名称。

然而有defect report 1477这似乎有意使这种命名空间外的定义格式良好。

在开CWG issue 1900这个问题被搁置,问题描述还得出结论,标准的规范文本不允许定义。它还指出,正如您所观察到的那样,存在实现差异。

对于 Clang,有一个关于类似案例的错误报告 here .

关于C++ 17 友元函数声明和内联命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59383156/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com