什么是内联命名空间?C ++ 11允许inline namespaces,其所有成员也自动在封闭中namespace。我想不出任何有用的应用 - 有人可以给出一个简短,简洁的例子,说明inline namespace需要哪种情况以及最常用的解决方案?(另外,当发生了什么并不清楚,我namespace声明inline在一个但不是所有的声明,这可能住在不同的文件。这难道不是找麻烦?)
3 回答
aluckdog
TA贡献1847条经验 获得超7个赞
除了上面的所有答案。
内联命名空间可用于编码符号中的ABI信息或函数版本。正是由于这个原因,它们被用于提供后向ABI兼容性。内联命名空间允许您在不更改API的情况下将信息注入到损坏的名称(ABI)中,因为它们仅影响链接器符号名称。
考虑这个例子:
假设您编写了Foo
一个引用对象的函数,bar
并且不返回任何内容。
在main.cpp中说
struct bar;void Foo(bar& ref);
如果在将文件编译为对象后检查此文件的符号名称。
$ nm main.o T__ Z1fooRK6bar
链接器符号名称可能会有所不同,但它肯定会在某处编码函数和参数类型的名称。
现在,它可能被bar
定义为:
struct bar{ int x;#ifndef NDEBUG int y;#endif};
根据构建类型,bar
可以引用具有相同链接器符号的两种不同类型/布局。
为了防止这种行为,我们将结构包装bar
到一个内联命名空间中,根据Build类型,链接器符号bar
将是不同的。
所以,我们可以写:
#ifndef NDEBUGinline namespace rel { #elseinline namespace dbg {#endifstruct bar{ int x;#ifndef NDEBUG int y;#endif};}
现在,如果您查看每个对象的目标文件,您可以使用release构建一个,另一个使用debug flag。您会发现链接器符号也包含内联命名空间名称。在这种情况下
$ nm rel.o T__ ZROKfoo9relEbar$ nm dbg.o T__ ZROKfoo9dbgEbar
链接器符号名称可能不同。
注意符号名称的存在rel
和dbg
符号名称。
现在,如果您尝试将调试与发布模式链接或反之亦然,则会出现链接器错误,这与运行时错误相反。
- 3 回答
- 0 关注
- 830 浏览
添加回答
举报
0/150
提交
取消