C ++:隐藏一些函数

时间:2010-12-11 11:20:04

标签: c++ math namespaces header scope

我重新定义了一些数学函数(因此它们更快 - 更准确 - 或者使用模板)。我将这些函数放在命名空间中,它们工作正常。

但是,我常常忘记调用我的命名空间中的函数(即:当我想调用mymath::cos时,我忘了写using mymath::cos;cos,而且它是很难找到我忘记的地方(直到现在我才发现它只是通过剖析)。

鉴于此

  • 在我的数学标题中包含标准math.hcmath标题,
  • 我需要包含标准的数学标题(因为我的一些函数只是标准函数的包装器,我希望它们是内联的,或者它们是模板化的),

是否有一种可移植的隐藏标准数学函数的方法,以便在使用全局命名空间(即:没有命名空间)数学函数时报告编译错误?

解决方案可能是在我的数学头文件的底部放置一个using namespace mymath;,但这个解决方案看起来并不那么好:它打破了命名空间的全部目的;我宁愿明确说明是否要使用mymathstd中的函数,这样我就不得不在溃烂或更准确的函数之间做出选择而不会忘记它。< / p>


修改

如果我使用全局命名空间中的cos(不使用std也不使用mymath),并且包含cmath(而不是math.h),很多答案都会说明,编译应该失败。

我不知道标准是怎么说的,但是:

#include <cmath>
int main( ) {
    cos( M_PI );
    return 0;
}

使用GNU GCC(g++)4.5.1(以及旧版本)进行编译。

7 个答案:

答案 0 :(得分:4)

将它放在头文件中,并将#include到任何地方:

namespace DontUseMe {  
double cos (double) ;  
// ...etc.  
}  
using namespace DontUseMe ;

答案 1 :(得分:3)

如果只包含cmath而不是math.h,则该标头中的所有函数都应该在std :: namespace中。永远不要使用using namespace std;,你会没事的。 (cmath只是math.h,其中包含命名空间中的所有内容)

答案 2 :(得分:2)

您是否需要在头文件中直接包含math.h和cmath标头?如果确实需要,请尝试包含如下标题:

namespace arbitrary_name
{
  #include <math.h>
}

这将包含新命名空间内的所有math.h定义,因此您不会在其他地方意外地使用它们。

这不是理想的解决方案。也许使用匿名命名空间有更好的方法,但解决方案对我来说并不清楚。

答案 3 :(得分:2)

不幸的是,最强大的解决方案是不使用与标准库相同的函数名称。幸运的是,标准函数名称简洁且大大缩写,因此诸如cosine()sine()exponent()arctan()之类的名称将是唯一的(并且可以说更好)而无需装饰名字含有笨拙的前缀。

或者,您可以保留相同的名称,但要将其大写:Sin()Cos()Exp()等。

答案 4 :(得分:1)

这个想法怎么样:包括&lt; math.h&gt;,使用如下定义:

#define sin blahblahblah    (just to generate an error)
#define cos blahblahblah    (just to generate an error)

所发生的事情是每一个罪都将被blahblahblah取代,这将导致错误。但是会发生什么是mymath :: sin将被mymath :: blahblahblah取代(因为#define字面意思),所以它也会产生错误。在这种情况下,如果你想让你的任务更容易,你只需在mymath中临时定义函数blahblahblah,以避免显示mymath :: sin的错误,然后编译并修复所有这些错误。

但是,我建议只进行“在文件中查找”并完成所有功能,我相信它不会超过一个小时的时间来讨论大型项目。

希望有所帮助。

的问候,
Rafid

答案 5 :(得分:1)

将一些包装函数写在一个单独的文件中。

#include <math.h>

namespace my_wrapper
{

float sin(float n)
{
    return std::sin(float n);
}

};

或类似的东西。然后只使用你的其他文件中的那些,甚至不包括或在其他soure文件中。是的,为他们编写转发功能是一件很小的痛苦,但这只是一次性工作而且没有那么多......

使用现代编译器来链接时间代码生成并且可以跨目标文件内联,这不应该是低效的......

答案 6 :(得分:0)

Clifford是我迄今为止最喜欢的答案,但您可以设想另一种选择:修改此项目的标准标题(仅限)。

您的编译器应该有一个选项来指示标准库所在的位置,因此您可以在项目中复制STL,并修改文件以便不再在全局名称空间中注入有问题的名称。 / p>

这是hackish,但这是我能想到的唯一方法,没有用脚本检查代码是否存在任何不合格的cos / sin(即紧接着{ {1}})。