如何从另一个命名空间而不是全局命名空间定义函数和数据?

Posted

技术标签:

【中文标题】如何从另一个命名空间而不是全局命名空间定义函数和数据?【英文标题】:How to define functions and data from another namespace, not in the global one? 【发布时间】:2014-11-30 13:26:36 【问题描述】:

如果我有一个带有一些声明的标题:

“头文件.hpp”

extern int SomeData;

int SomeFunc();

以及它的一个实现(我在一个未命名的命名空间中声明了所有函数和全局变量,以避免链接问题):

“头文件.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()

所以无论如何我可以将所有本地文件符号声明在匿名命名空间中,以避免链接问题,但同时能够定义我的函数和数据导出。

【问题讨论】:

您是否尝试在外部符号SomeDataSomeFunc 之前结束匿名命名空间?在同一个翻译单元中,他们应该可以访问您在匿名命名空间中的本地定义。 所以我无法在另一个命名空间中定义我的全局函数? 函数应该在声明它们的命名空间中定义。但是,您可以在全局命名空间中定义全局函数,这些函数使用在匿名命名空间中定义的局部符号(参见我的回答如下)。 【参考方案1】:

您不能在匿名命名空间中定义全局范围的对象。

如果您想与其他编译单元共享SomeDataSomeFunc(),您只需在您的命名空间之外定义它们。

匿名命名空间旨在避免您的符号在其编译单元之外共享。因此,如果您不想共享符号,请在匿名命名空间中定义它们。在头文件中声明它们不会使它们对其他编译单元可用。如果您希望将定义保留在仅包含在此文件中的标头中,则可以以相同的方式将定义包含在匿名名称空间中。

【讨论】:

【参考方案2】:

我相信您在 Header.cpp 文件中尝试执行的操作是:

inline namespace

  const int SomeLocalFileData = 9;

  struct MyLocalStructure;

  int SomeLocalFunction(MyLocalStructure *);


int SomeData(SomeLocalFileData);

int SomeFunc()

    return SomeLocalFunction(nullptr);

在同一个翻译单元和匿名命名空间之后,SomeDataSomeFunc 的定义可以访问该匿名命名空间中定义的本地符号(例如 SomeLocalFileDataMyLocalStructureSomeLocalFunction)。这些符号将对其他翻译单元保持隐藏。

【讨论】:

以上是关于如何从另一个命名空间而不是全局命名空间定义函数和数据?的主要内容,如果未能解决你的问题,请参考以下文章

PHP中命名空间是怎样的存在?

如何从另一个包中只导入一个函数,而不加载整个命名空间

php命名空间的设计思想和缺点

命名空间

在除 ADL、“本地”或全局命名空间之外的命名空间中定义函数

如何在另一个 C++ 命名空间内的全局命名空间中定义朋友?