通过 using-directive 或 using-declaration 引入的名称可以用作友元声明的详细类型说明符吗?

问题描述 投票:0回答:1

为什么gcc、clang、msvc能成功编译以下代码? (神箭)

namespace impl {
class A;
} // namespace impl

namespace api {
using namespace impl;
} // namespace api

class B
{
    friend class api::A;     // (1)
};

在我看来,这种特殊类型的友元声明需要详细类型说明符。详细类型说明符是

class
关键字,后跟类名。但是这个翻译单元中没有名为
api::A
的类。 using-directive 不声明此类,它仅影响名称查找规则。因此,我预计标记为
(1)
的行的编译会失败,并出现错误,即命名空间
class
中没有
api
A。但主要编译器接受它......我错过了什么?

还有后续问题:如果我将 using-directive

using namespace impl;
替换为 using-declaration
using impl::A;
,那么真的会在命名空间
A
中声明名称
api
,从而使代码格式良好?

c++ c++17 language-lawyer friend using-directives
1个回答
0
投票

为了了解发生了什么,我们必须查看代码的每个元素:

namespace impl {
    class A;
};

是一个声明

namespace
class A

namespace api {
    using namespace impl;
};

是一个使用

namespace
namespace impl
,其中声明了
class A

class B
{
    friend class api::A;     // (1)
};

是一个具有声明的

class
,它告诉编译器,
class A
位于使用
namespace api
namespace impl
中,是
friend
class B

它本质上是一条链条。

B::api
->
api::impl
->
impl::A

© www.soinside.com 2019 - 2024. All rights reserved.