为什么在< cmath>不是在std命名空间? [英] Why are some functions in <cmath> not in the std namespace?

查看:448
本文介绍了为什么在< cmath>不是在std命名空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用多种算术类型的项目。因此,我制作了一个标题,其中定义了用户定义的算术类型的最低要求:



user_defined_arithmetic.h:

  typedef double ArithmeticF; //用户选择什么类型他
//想用来表示一个实数

命名空间算术//并定义与该类型相关的函数
{

const算术F sin(const ArithmeticF& x);
const ArithmeticF cos(const ArithmeticF& x);
const ArithmeticF tan(const ArithmeticF& x);
...
}

令我困扰的是,代码如下:

  #includeuser_defined_arithmetic.h

void some_function()
{
using namespace arithmetic;
ArithmeticF lala(3);
sin(lala);
}



我遇到编译错误:

 错误:调用重载的sin(ArithmeticF&)是不明确的
候选是:
double sin(double)
const ArithmeticF我从来没有使用过< $($)。 ; math.h> 头,只有< cmath> 。我从来没有在头文件中使用 using namespace std



我使用gcc 4.6。*。我检查了包含歧义声明的标头是什么,结果是:



mathcalls.h: b

 数学函数的原型声明; < math.h>的帮助文件。 
...



我知道,< cmath> 包括< math.h> ,但它应该用std命名空间屏蔽声明。我深入了< cmath> 标题,并找到:



cmath.h:

  ... 

#include< math.h>

...

//除去在< math.h>中定义的那些宏,代替实际功能。
#undef abs
#undef div
#undef acos
...

命名空间std _GLIBCXX_VISIBILITY(默认)
{
...

因此,命名空间std在之后 $ c> #include< math.h>

解决方案

允许C ++标准库的实现声明C库函数在全局命名空间以及 std 中。有些人会认为这是一个错误,因为(如你所发现的)命名空间污染可能会导致与你自己的名字冲突。然而,这是它的方式,所以我们必须生活在它。你只需要将你的名字命名为 arithmetic :: sin



C ++ 11 17.6.1.2/4):


然而,在C ++标准库中,声明在C中定义为宏的名称位于命名空间 std 的命名空间范围(3.3.6)中。 它是
未指定这些名称是否首次在全局命名空间范围内声明
,然后通过显式使用声明(7.3.3)注入
到命名空间std中。



I am developing a project which works with multiple arithmetic types. So I made a header, where the minimal requirements for a user defined arithmetic type are defined:

user_defined_arithmetic.h :

typedef double ArithmeticF;   // The user chooses what type he 
                              // wants to use to represent a real number

namespace arithmetic          // and defines the functions related to that type
{

const ArithmeticF sin(const ArithmeticF& x);
const ArithmeticF cos(const ArithmeticF& x);
const ArithmeticF tan(const ArithmeticF& x);
...
}

What is troubling me is that when I use code like this:

#include "user_defined_arithmetic.h"

void some_function()
{
    using namespace arithmetic;
    ArithmeticF lala(3);
    sin(lala);
}

I get a compiler error:

error: call of overloaded 'sin(ArithmeticF&)' is ambiguous
candidates are:
double sin(double)
const ArithmeticF arithmetic::sin(const ArithmeticF&)

I have never used the <math.h> header, only the <cmath>. I have never used the using namespace std in a header file.

I am using gcc 4.6.*. I checked what is the header containing the ambiguous declaration and it turns out to be:

mathcalls.h :

Prototype declarations for math functions; helper file for <math.h>.
...

I know, that <cmath> includes <math.h>, but it should shield the declarations by the std namespace. I dig into the <cmath> header and find:

cmath.h :

...

#include <math.h>

...

// Get rid of those macros defined in <math.h> in lieu of real functions.
#undef abs
#undef div
#undef acos
...

namespace std _GLIBCXX_VISIBILITY(default)
{
...

So the namespace std begins after the #include <math.h>. Is there something wrong here, or did I misunderstand something?

解决方案

Implementations of the C++ standard library are permitted to declare C library functions in the global namespace as well as in std. Some would call this a mistake, since (as you've found) the namespace pollution can cause conflicts with your own names. However, that's the way it is, so we must live with it. You'll just have to qualify your name as arithmetic::sin.

In the words of the standard (C++11 17.6.1.2/4):

In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).

这篇关于为什么在&lt; cmath&gt;不是在std命名空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆