【发布时间】:2012-09-01 16:52:28
【问题描述】:
可能重复:
Is it a good idea to wrap an #include in a namespace block?
我在全局命名空间 (::log) 中有一个类 log 的项目。
所以,很自然,在#include <cmath> 之后,每次我尝试实例化我的日志类的对象时,编译器都会给出一条错误消息,因为<cmath> 用许多三字母方法污染了全局命名空间,其中之一为对数函数log()。
所以有三种可能的解决方案,每一种都有其独特的丑陋副作用。
- 将日志类移动到它自己的命名空间,并始终使用它的完全限定名称访问它。我真的想避免这种情况,因为记录器应该尽可能方便使用。
- 编写一个
mathwrapper.cpp文件,这是项目中唯一包含<cmath>的文件,并通过namespace math中的包装器使所有必需的<cmath>函数可用。我不想使用这种方法,因为我必须为每个所需的数学函数编写一个包装器,并且会增加额外的调用惩罚(由-flto编译器标志部分取消) - 我目前正在考虑的解决方案:
替换
#include <cmath>
通过
namespace math {
#include "math.h"
}
然后通过math::log()计算对数函数。
我已经尝试过了,它确实可以按预期编译、链接和运行。但是,它确实有多个缺点:
- (显然)不可能使用
<cmath>,因为<cmath>代码通过其完全限定名称访问函数,并且不推荐在 C++ 中使用。 - 我有一种非常非常糟糕的感觉,就像我是gonna get attacked and eaten alive by raptors.
所以我的问题是:
- 是否有任何建议/约定/等禁止在命名空间中放置包含指令?
-
有什么问题吗
- 不同的 C 标准库实现(我使用 glibc),
- 不同的编译器(我使用 g++ 4.7,-std=c++11),
- 链接?
- 您是否尝试过这样做?
- 是否有其他方法可以从全局命名空间中消除数学函数?
我在 stackoverflow 上发现了几个类似的问题,但大多数都是关于包含其他 C++ 头文件的,这显然是一个坏主意,而且那些没有对 C 库的链接行为做出矛盾的陈述。另外,将#include <math.h> 额外放在extern "C" {} 中是否有益?
编辑
所以我决定做可能其他人都在做的事情,并将我的所有代码放在项目命名空间中,并在包含 <cmath> 时使用它的完全限定名称访问记录器。
【问题讨论】:
-
错了。有很多原因 :) 你可以做到(它会编译,甚至看起来像你认为你正在尝试做的事情)......但你应该 '不。 正确的事情是把你的命名空间声明inside每个头文件。恕我直言...
-
@paulsm4 为什么?您引用了“很多原因”,但没有提供任何原因。因为我们显然不会去编辑我们编译的每个系统上的标准头文件,也不会分发我们自己的,所以似乎非常合乎逻辑地使用名称间距功能将 c 函数从全局命名空间中取出。
标签: c++ namespaces include