gpt4 book ai didi

c++ - 什么是内联命名空间?

转载 作者:bug小助手 更新时间:2023-10-28 01:31:52 25 4
gpt4 key购买 nike

C++11 允许 inline namespace,其所有成员也自动位于封闭的 namespace 中。我想不出任何有用的应用程序——有人可以给出一个简短的例子来说明需要 inline namespace 以及它是最惯用的解决方案的情况吗?

(另外,我不清楚当 namespace 被声明为 inline 时会发生什么,但不是所有声明,它们可能存在于不同的文件中。是'这不是自找麻烦吗?)

最佳答案

内联命名空间是类似于 symbol versioning 的库版本控制功能,但纯粹在 C++11 级别(即跨平台)实现,而不是作为特定二进制可执行格式的功能(即特定于平台)。

这是一种机制,库作者可以通过该机制使嵌套命名空间看起来并像其所有声明都在周围的命名空间中一样(内联命名空间可以嵌套,因此“更多嵌套”的名称一直渗透到第一个非内联命名空间,并且看起来和行为就好像它们的声明也在两者之间的任何命名空间中一样)。

vector 的 STL 实现为例。 .如果我们从 C++ 开始就有内联命名空间,那么在 C++98 中,标题 <vector>可能看起来像这样:

namespace std {

#if __cplusplus < 1997L // pre-standard C++
inline
#endif

namespace pre_cxx_1997 {
template <class T> __vector_impl; // implementation class
template <class T> // e.g. w/o allocator argument
class vector : __vector_impl<T> { // private inheritance
// ...
};
}
#if __cplusplus >= 1997L // C++98/03 or later
// (ifdef'ed out b/c it probably uses new language
// features that a pre-C++98 compiler would choke on)
# if __cplusplus == 1997L // C++98/03
inline
# endif

namespace cxx_1997 {

// std::vector now has an allocator argument
template <class T, class Alloc=std::allocator<T> >
class vector : pre_cxx_1997::__vector_impl<T> { // the old impl is still good
// ...
};

// and vector<bool> is special:
template <class Alloc=std::allocator<bool> >
class vector<bool> {
// ...
};

};

#endif // C++98/03 or later

} // namespace std

取决于 __cplusplus 的值, 一个或另一个 vector选择实现。如果您的代码库是用 C++98 之前的版本编写的,并且您发现 vector 的 C++98 版本当您升级编译器时给您带来麻烦,“所有”您要做的就是找到对 std::vector 的引用在您的代码库中并将它们替换为 std::pre_cxx_1997::vector .

下一个标准来了,STL 供应商只是再次重复这个过程,为 std::vector 引入一个新的命名空间。与 emplace_back支持(需要 C++11)并内联那个 iff __cplusplus == 201103L .

好的,那我为什么需要一个新的语言功能呢?我已经可以执行以下操作以达到相同的效果,不是吗?

namespace std {

namespace pre_cxx_1997 {
// ...
}
#if __cplusplus < 1997L // pre-standard C++
using namespace pre_cxx_1997;
#endif

#if __cplusplus >= 1997L // C++98/03 or later
// (ifdef'ed out b/c it probably uses new language
// features that a pre-C++98 compiler would choke on)

namespace cxx_1997 {
// ...
};
# if __cplusplus == 1997L // C++98/03
using namespace cxx_1997;
# endif

#endif // C++98/03 or later

} // namespace std

取决于 __cplusplus 的值,我得到了其中一个实现。

你几乎是正确的。

考虑以下有效的 C++98 用户代码(在 C++98 中已经允许完全特化位于命名空间 std 中的模板):

// I don't trust my STL vendor to do this optimisation, so force these 
// specializations myself:
namespace std {
template <>
class vector<MyType> : my_special_vector<MyType> {
// ...
};
template <>
class vector<MyOtherType> : my_special_vector<MyOtherType> {
// ...
};
// ...etc...
} // namespace std

这是完全有效的代码,其中用户为一组类型提供自己的 vector 实现,而她显然知道比在 STL(她的拷贝)中找到的更有效的实现。

但是:当特化一个模板时,你需要在它被声明的命名空间中这样做。标准说 vector在命名空间 std 中声明,所以这是用户理所当然希望专门化该类型的地方。

此代码适用于非版本化命名空间 std ,或使用 C++11 内联命名空间功能,但不使用使用 using namespace <nested> 的版本控制技巧,因为这暴露了 vector 所在的真正命名空间的实现细节。定义不是 std直接。

您可以通过其他漏洞检测嵌套命名空间(请参阅下面的注释),但内联命名空间会将它们全部塞住。这就是它的全部。对 future 非常有用,但 AFAIK 标准并没有为它自己的标准库规定内联命名空间名称(不过我很想被证明是错误的),所以它只能用于第三方库,而不是标准本身(除非编译器供应商同意命名方案)。

关于c++ - 什么是内联命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11016220/

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