问题描述
我有一个项目在全局命名空间中有一个类 log
code> :: log )。
I've got a project with a class log
in the global namespace (::log
).
所以,在后面,#include< cmath>
,每次尝试实例化我的日志类的对象时,编译器会给出错误消息,因为< cmath>
的三字母方法,其中一个是对数函数 log()
。
So, naturally, after #include <cmath>
, the compiler gives an error message each time I try to instantiate an object of my log class, because <cmath>
pollutes the global namespace with lots of three-letter methods, one of them being the logarithm function log()
.
- 将日志类移动到自己的命名空间,并始终使用它的完全限定名称访问它。我真的想避免这样,因为记录器应该尽可能方便使用。
- 编写一个
mathwrapper.cpp
项目中包含< cmath>
的唯一文件,并使所有必需的< cmath>
通过命名空间数学
中的封装。我不想使用这种方法,因为我必须为每一个所需的数学函数写一个包装,并且它会增加额外的调用惩罚(部分由-flto
compiler flag) - 我正在考虑的解决方案:
- Move the log class to it's own namespace and always access it with it's fully qualified name. I really want to avoid this because the logger should be as convenient as possible to use.
- Write a
mathwrapper.cpp
file which is the only file in the project that includes<cmath>
, and makes all the required<cmath>
functions available through wrappers in anamespace math
. I don't want to use this approach because I have to write a wrapper for every single required math function, and it would add additional call penalty (cancelled out partially by the-flto
compiler flag) - The solution I'm currently considering:
>
Replace
#include <cmath>
由
namespace math {
#include "math.h"
}
然后通过 math :: log()
计算对数函数。
and then calculating the logarithm function via math::log()
.
它确实,确实,编译,链接和运行如预期。但它有多种缺点:
I have tried it out and it does, indeed, compile, link and run as expected. It does, however, have multiple downsides:
- 很显然不可能使用
< cmath> code>,因为
< cmath>
代码通过其完全限定名访问函数,并且不推荐在C ++中使用。 - 我有一个真正的,非常糟糕的感觉,像我会被攻击,并由猛禽吃活。
- It's (obviously) impossible to use
<cmath>
, because the<cmath>
code accesses the functions by their fully qualified names, and it's deprecated to use in C++. - I've got a really, really bad feeling about it, like I'm gonna get attacked and eaten alive by raptors.
所以我的问题是:
- Is there any recommendation/convention/etc that forbid putting include directives in namespaces?
Could anything go wrong with
- 不同的标准库实现(我使用glibc),
- 不同的编译器(我使用g ++ 4.7,-std = c ++ 11) >
>
- diferent C standard library implementations (I use glibc),
- different compilers (I use g++ 4.7, -std=c++11),
- linking?
我在stackoverflow上发现了几个类似的问题,但是,大多数是关于包括其他C + +头文件,这显然是一个坏主意,那些没有作出矛盾的陈述关于链接C库的行为。此外,将 #include
在 externC{}
?
I've found several similar questions on stackoverflow, but most were about including other C++ headers, which obviously is a bad idea, and those that weren't made contradictory statements about linking behaviour for C libraries. Also, would it be beneficial to additionally put the #include <math.h>
inside extern "C" {}
?
编辑
所以我决定做可能其他人执行并将所有代码放在项目命名空间中,并在包含< cmath>
时访问带有完全限定名称的日志记录器。
So I decided to do what probably everyone else is doing, and put all of my code in a project namespace, and to access the logger with it's fully qualified name when including <cmath>
.
推荐答案
不,您正在考虑的解决方案是不允许的。在实践中,这意味着你正在改变头文件的含义。
No, the solution that you are considering is not allowed. In practice what it means is that you are changing the meaning of the header file. You are changing all of its declarations to declare differently named functions.
这些改变的声明与标准库函数的实际名称不匹配,所以在链接时,无的标准库函数将解析对已更改的声明声明的函数的调用,除非它们恰好被声明为 externC
,但这不是推荐的 -
These altered declarations won't match the actual names of the standard library functions so, at link time, none of the standard library functions will resolve calls to the functions declared by the altered declarations unless they happen to have been declared extern "C"
which is allowed - but not recommended - for names which come from the C standard library.
ISO / IEC 14882:2011 17.6.2.2/3 [using.headers]适用于C标准库头文件,因为它们是
ISO/IEC 14882:2011 17.6.2.2/3 [using.headers] applies to the C standard library headers as they are part of the C++ standard library:
[*]这将包括在翻译单元中的第一引用之前的标题。命名空间定义。
[*] which would include a namespace definition.
这篇关于是否可以在命名空间中放置标准的纯C头#include指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!