【问题标题】: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 之前结束匿名命名空间?在同一个翻译单元中,他们应该可以访问您在匿名命名空间中的本地定义。
  • 所以我无法在另一个命名空间中定义我的全局函数?
  • 函数应该在声明它们的命名空间中定义。但是,您可以在全局命名空间中定义全局函数,这些函数使用在匿名命名空间中定义的局部符号(参见我的回答如下)。

标签: c++ c++11 gcc namespaces


【解决方案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)。这些符号将对其他翻译单元保持隐藏。

    【讨论】:

      猜你喜欢
      • 2011-01-15
      • 2012-08-06
      • 2011-01-13
      • 2013-11-19
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 2019-10-29
      • 1970-01-01
      相关资源
      最近更新 更多