【问题标题】:C++: Instantiate object with no namespaceC++:实例化没有命名空间的对象
【发布时间】:2019-05-12 05:08:23
【问题描述】:

我被两个.hpp 文件困住了,它们有很多共享相同名称的类/方法等等。我的问题是 A.hpp 被包裹在 namespace 中,所以我可以使用任何我想要使用的东西> A::className objName(...);

但是我不知道如何使用来自B.hpp 的任何东西,它没有包装在命名空间中,所以我不能写B::className objName(...)

要求访问以更改任何 .hpp 文件(我只是将 B 包装在命名空间中)的过程大约需要一天时间,因此我正在寻找替代且更快的解决方案。

谢谢。

【问题讨论】:

  • 如果它没有包含在命名空间 B 中,则跳过 B:: 并在执行 #include "B.hpp" 后直接使用名称
  • 我试过了,不行。它仍然说“对Class 的引用不明确”
  • @Rorschach 如果是这种情况,您可以将 B 包装在命名空间中吗?如果这两个共享命名函数/成员,那么为它们提供单独的命名空间是个好主意
  • @Tom 是的,正如我所说,我需要向系统管理员发送电子邮件,等待他们到chmod 这个文件,等等等等,这就是我寻找替代方案的原因。但是,是的,我相信这会奏效。
  • 某处可能存在“使用命名空间 A”,请尝试删除它。

标签: c++ class namespaces


【解决方案1】:

首先,并且可能是最安全的,您可以通过在名称前加上一元范围运算符 :: 来明确限定在全局范围内的查找:

::classFromB foo(/*...*/);
::globalFuncFromB( foo, &::globalVarFromB ); // Obviously this gets rather tedious.

其次,假设没有using指令(using namespace A;)或声明(using conflictsWithB = A::className),或其他声明,产生冲突,一般可以依靠不合格查找:

classFromB foo(/*...*/);
globalFuncFromB( foo, &globalVarFromB  );

最后,您可以将包含文件的全部内容包装在命名空间中:

namespace B {
#include "B.hpp"
}

这有许多潜在的问题,特别是如果 B.hpp 中的任何声明被假定或实际定义在标头本身或其他地方(实现 B.cpp?)在全局范围内。不是最好的主意,但有时很有用。 如果您考虑这种方法,请务必谨慎。

【讨论】:

  • 谢谢,第一个选项效果很好,直到我可以访问更改文件并将所有内容包装在两个单独的命名空间中。
  • 如果B.hpp 中声明的任何函数或对象在单独的编译单元中定义,则将头文件包含在命名空间中将不起作用。特别是,如果这些函数的源或定义这些对象的源不可用(例如,仅在编译的对象或库中可用),它将不起作用。
  • @Peter 这就是我在该选项之后的注释的预期含义。从本质上讲,它可以工作,但通常不会 - 甚至会产生可以工作的部分和不工作的部分的混合。
  • @pandorafalters - 可能更容易说它仅在标头定义它声明的所有内容时才有效。例如,如果 B 是一个仅包含标头的库(并且命名空间 B 不是 std 或它的别名,因为在 std 中声明名称会在除某些特定情况下提供未定义的行为)。
  • @Peter 我试图在一个简短的警告中解决最广泛的可能性,也许很糟糕。例如,如果任何“内部”查找被明确限定,即使是仅包含标头的库也可能在包含到命名空间时失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
  • 2019-03-12
相关资源
最近更新 更多