就像我有一个带有一些声明的标题:
" Header.hpp"
extern int SomeData;
int SomeFunc();
以及它的实现(其中我在未命名的命名空间中声明所有函数和全局变量以避免链接问题):
" Header.cpp"
#include "Header.hpp"
inline namespace
{
const int SomeLocalFileData = 9;
struct MyLocalStructure;
int SomeLocalFunction(MyLocalStructure *);
int ::SomeData(SomeLocalFileData);
int ::SomeFunc()
{
return SomeLocalFunction(nullptr);
}
}
以上代码将失败并出现以下错误(使用' gcc'编译器):
错误:声明' SomeData'不在围绕' ::'的名称空间中 int :: SomeData(SomeLocalFileData);
错误:声明' int SomeFunc()'不在命名空间周围 ' ::' int :: SomeFunc()
那么无论如何我可以将所有本地文件符号声明为匿名命名空间,以避免链接问题但同时能够定义我的函数和数据导出。
答案 0 :(得分:2)
不允许在匿名命名空间中定义全局范围的对象。
如果要与其他编译单元共享SomeData
和SomeFunc()
,则只需在命名空间外定义它们即可。
匿名命名空间旨在避免您的符号在其编译单元之外共享。因此,如果您不想共享符号,请在匿名命名空间中定义它们。在标题中声明它们将不会使它们可用于其他编译单元。如果要将定义保留在仅包含在此文件中的标头中,则可以以相同的方式将定义括在匿名命名空间中。
答案 1 :(得分:2)
我相信您在Header.cpp
文件中尝试执行的操作是:
inline namespace
{
const int SomeLocalFileData = 9;
struct MyLocalStructure;
int SomeLocalFunction(MyLocalStructure *);
}
int SomeData(SomeLocalFileData);
int SomeFunc()
{
return SomeLocalFunction(nullptr);
}
在同一个翻译单元中,在匿名命名空间之后,SomeData
和SomeFunc
的定义可以访问本地符号(例如SomeLocalFileData
,MyLocalStructure
和{{ 1}})在匿名命名空间中定义。这些符号将保持对其他翻译单元的隐藏。