gpt4 book ai didi

c++ - 为什么标准库类型可以在 `std` 内部访问,尽管它们嵌套在实现定义的命名空间中?

转载 作者:行者123 更新时间:2023-12-05 08:45:49 26 4
gpt4 key购买 nike

我正在浏览 <optional> 的实现GCC 11.2 的 header (可在 here 中找到),我注意到一些我难以理解的东西。这是 header ,(希望如此)只遗漏了重要的部分:

#ifndef _GLIBCXX_OPTIONAL
#define _GLIBCXX_OPTIONAL 1

#pragma GCC system_header

#if __cplusplus >= 201703L

/* Includes of various internal and library headers */

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#if __cplusplus == 201703L
# define __cpp_lib_optional 201606L
#else
# define __cpp_lib_optional 202106L
#endif

/* Implementation */

template<typename _Tp>
class optional;

/* Implementation */

template<typename _Tp>
class optional: /* Implementation */
{ /* Implementation */ };

/* Implementation */


_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++17

#endif // _GLIBCXX_OPTIONAL

我发现 _GLIBCXX_BEGIN_NAMESPACE_VERSION_GLIBCXX_END_NAMESPACE_VERSION扩展到 namespace __8 {} ,分别(在 inline 之前没有 namespace __8)。

因此,它看起来像std::optional实际上是在非内联命名空间 std::__8 中定义的, 但尽管如此,我显然可以引用 std::optional在我的程序中就好像它直接位于 std 中一样.

我不认为有任何 using有效的指令,首先是因为我还没有找到任何指令,其次是因为应该允许它专门化 std::optional对于自定义类型,无需打开实现定义的命名空间([namespace.std#2][temp.spec.partial.general#6])。

_GLIBCXX_VISIBILITY(default)宏扩展为 __attribute__ ((__visibility__ ("default"))) ,但我认为它不相关( documentation )。我找不到 system_header在文档中的 pragma 列表中。

因此,我不明白为什么我应该能够将可选类引用为 std::optional而不是 std::__8::optional .我在这里缺少什么?

最佳答案

libstdc++ 中定义这些宏的c++config 最初也将版本命名空间声明为inline here :

// Defined if inline namespaces are used for versioning.
#define _GLIBCXX_INLINE_VERSION

// Inline namespace for symbol versioning.
#if _GLIBCXX_INLINE_VERSION
# define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __8 {
# define _GLIBCXX_END_NAMESPACE_VERSION }

namespace std
{
inline _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201402L
inline namespace literals {
inline namespace chrono_literals { }
inline namespace complex_literals { }
inline namespace string_literals { }
#if __cplusplus > 201402L
inline namespace string_view_literals { }
#endif // C++17
}
#endif // C++14
_GLIBCXX_END_NAMESPACE_VERSION
}

一旦一个命名空间被声明为inline,它总是inline。例如:

namespace A {
inline namespace B {
struct X { };
}
}

namespace A {
namespace B {
struct Y { };
}
}

A::X x; // ok
A::Y y; // still ok

即使 gcc 没有发出警告,clang 也会发出警告,但它也是一个系统头文件,因此即使 gcc 发出警告也没有关系。

仍然不确定为什么不直接将 inline 添加到宏定义中。我们可能还没有达到每个 header 额外 7 个字符对编译时间造成重大损害的地步?

关于c++ - 为什么标准库类型可以在 `std` 内部访问,尽管它们嵌套在实现定义的命名空间中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71607148/

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