可能的重复:
将 #include 包装在命名空间块中是个好主意吗? https://stackoverflow.com/questions/6670738/is-it-a-good-idea-to-wrap-an-include-in-a-namespace-block
我有一个带有课程的项目log
在全局命名空间中(::log
).
那么,自然而然地,之后#include <cmath>
,每次我尝试实例化日志类的对象时,编译器都会给出错误消息,因为<cmath>
用许多三字母方法污染全局命名空间,其中之一是对数函数log()
.
因此存在三种可能的解决方案,每种都有其独特的丑陋副作用。
- 将日志类移至其自己的命名空间,并始终使用其完全限定名称来访问它。我真的想避免这种情况,因为记录器应该尽可能方便使用。
- Write a
mathwrapper.cpp
文件,这是项目中唯一包含的文件<cmath>
,并使所有所需的<cmath>
通过包装器可用的功能namespace math
。我不想使用这种方法,因为我必须为每个所需的数学函数编写一个包装器,并且它会增加额外的调用惩罚(由-flto
编译器标志)
- 我目前正在考虑的解决方案:
Replace
#include <cmath>
by
namespace math {
#include "math.h"
}
然后通过计算对数函数math::log()
.
我已经尝试过,它确实按预期编译、链接和运行。然而,它确实有多个缺点:
- (显然)不可能使用
<cmath>
,因为<cmath>
代码通过函数的完全限定名称来访问函数,并且不推荐在 C++ 中使用它。
- 我有一种非常非常不好的预感会被猛禽袭击并活活吃掉。 http://xkcd.com/292/
所以我的问题是:
- 是否有任何建议/约定/等禁止将 include 指令放入命名空间?
-
有什么问题吗
- 不同的C标准库实现(我使用glibc),
- 不同的编译器(我使用 g++ 4.7,-std=c++11),
- linking?
- 你有尝试过这样做吗?
- 是否有其他方法可以从全局命名空间中消除数学函数?
我在 stackoverflow 上发现了几个类似的问题,但大多数都是关于包含其他 C++ 头文件,这显然是一个坏主意,而且那些没有对 C 库的链接行为做出矛盾的陈述。另外,另外添加#include <math.h>
inside extern "C" {}
?
edit
因此,我决定做其他人可能正在做的事情,并将所有代码放在项目命名空间中,并在包含时使用其完全限定名称访问记录器<cmath>
.
不,您正在考虑的解决方案是不允许的。实际上,这意味着您正在更改头文件的含义。您正在更改其所有声明以声明不同名称的函数。
这些更改的声明与标准库函数的实际名称不匹配,因此在链接时,标准库函数都不会解析对更改的声明所声明的函数的调用,除非它们碰巧已声明extern "C"
对于来自 C 标准库的名称,这是允许的,但不推荐。
ISO/IEC 14882:2011 17.6.2.2/3 [using.headers] 适用于 C 标准库头,因为它们是 C++ 标准库的一部分:
翻译单元应仅在任何外部声明或定义[*]之外包含标头,并且应在该翻译单元中对该标头中声明的任何实体的第一次引用之前按词法包含该标头。
[*] 其中将包括名称空间定义。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)