【问题标题】:Namespaces in C HeadersC 头文件中的命名空间
【发布时间】:2013-04-29 17:09:36
【问题描述】:

我们有一个代码库,其中有 .cpp 和 .h,它被设置为使用 gcc 构建

我的理解是 gcc 将为适当的文件选择适当的编译器,所以我相信(并且测试使我几乎 100% 确定)我们的 .h 文件被编译为 c 而我们的 .cpp 文件被编译为 C++。

我曾经尝试更改为 g++ 并遇到大量错误,当我尝试使用 .hpp 时也是如此。

所以为了解决这个问题,大多数时候我只是在需要时使用 extern C++(例如在包含地图时)

但是,我似乎无法将其用于命名空间。我假设编译器抱怨我的命名空间,因为它被编译为 .h?这个对吗。我当前的代码看起来像(在没有 extern 的情况下尝试之后):

在 foo.h 中

 extern "C++" {
 namespace Caching_Logic
 {
      class foo
      {
         ....
      }
 }
 }

在 bar.h 中

 extern "C++" {
       using namespace Caching_Logic; //completely defeats the point of namespaces
 }
 class bar
 {
   ....

          foo m_foo;

   ...
 }

这两个文件都包含在 .cpp 文件中

编译时的错误是:

filethatusesbar.cpp:错误:“class bar”没有名为“m_foo”的成员

bar.h : 错误:“Caching_Logic”不是命名空间名称

bar.h : 错误:';' 标记之前的预期命名空间名称

我正在考虑完全放弃命名空间,但我真的很想为此设置我的代码范围!

-----更新-----

看完http://www.network-theory.co.uk/docs/gccintro/gccintro_54.html

我对 gcc 的作用有了更好的理解。最初我在某处读到 gcc 在必要时在 C++ 中编译,在遇到 .c 时在 C 中编译

这是真的,但链接器似乎存在问题。由于这是作为库编译的,因此我以前从未见过问题是有道理的。我猜这与我的范围问题,外部链接有关?

【问题讨论】:

  • 您不需要(在大多数情况下甚至不应该)extern "C++"。这是默认设置。即使您的标头被编译为 C(它们不是),AFAIK 标准 C 编译器甚至不知道如何处理 extern "C++",更不用说提及类和命名空间了。这就是所有 C++ 语法。
  • C 对命名空间一无所知。为什么你认为它会编译?
  • 我发现 extern "C++" 过去可以工作,正如我在帖子中提到的,如果我在头文件中 #include 映射,它不喜欢它,但是如果我把它包装进去跨度>
  • extern C++ 它可以工作我认为最终的问题是,尽管 gcc 会将 cpp 源文件编译为 c++ 并且可以清楚地了解它最终链接的 extern C++,就好像我都是 c @987654322 @ 所以我认为我真的必须表现得好像我在 C 中一样
  • 如果您的标头被处理为 C,您会收到如下错误; “错误:预期的标识符或字符串常量之前的'('。”您可以尝试通过运行gcc -c -x c foo.h 之类的命令将标头编译为c 源代码。事实上,您在extern "C++" { 之类的源代码上没有收到错误,这不是有效的 C,证明您的标头没有被作为 C 处理。您可能需要了解有关 C 和 C++ 的编译模型的更多信息,因为标头根本没有按照您描述的方式处理。

标签: c++ c namespaces extern


【解决方案1】:

您的 .h 文件未编译为 C。它们包含在您的 *.cpp 文件中,预处理组合由您的 C++ 编译器编译。

确认您在 bar.h 中的问题行之前的某处有 #included foo.h。否则可能会导致编译器错误。更喜欢#include它在bar.h中,它最清楚自己的物理依赖关系。

如注释所述,bar.h 中的 using 指令被认为是有害的。考虑改用这个:

class bar {
    ....
    Caching_Logic::foo m_foo;

【讨论】:

  • 绝对包含在里面
  • 是的,范围运算符也不起作用,这就是为什么我尝试使用命名空间只是为了看看它是否有效。我的错误来自那个编译并且更干净一些,所以这就是我发布的代码
  • 其他尝试:复制/粘贴命名空间名称,以确保其相同;通过删除不必要的外部“C++”括号来简化;使用 g++ -E 获取预处理后的输出,并验证 foo.h 的内容出现在 bar.h 之前,并在预处理后按预期出现。
  • 我能问一下,如果 extern C++ 不是用 c 编译的话,为什么会有不同?
  • 解决编译器错误的一个通用策略是简化问题,使其更易于理解,并消除导致问题的潜在因素。在这里,外部 C++ 可能是无辜的。但是您可以通过消除它轻松地保证它不是一个因素。
猜你喜欢
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
相关资源
最近更新 更多