为什么<cmath>中有一些函数不在 std 命名空间中? [英] Why are some functions in <cmath> not in the std namespace?

查看:39
本文介绍了为什么<cmath>中有一些函数不在 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&)

我从未使用过 <math.h> 标头,只使用过 <cmath>.我从未在头文件中使用过 using namespace std.

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

我正在使用 gcc 4.6.*.我检查了包含模棱两可声明的标题是什么,结果是:

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

ma​​thcalls.h:

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

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

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)
{
...

所以命名空间std在#include <math.h>之后开始.这里有什么问题,还是我误会了什么?

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

推荐答案

允许 C++ 标准库的实现在全局命名空间以及 std 中声明 C 库函数.有些人会称这是一个错误,因为(正如您所发现的)命名空间污染会导致与您自己的名称发生冲突.然而,事情就是这样,所以我们必须忍受它.您只需将您的名字限定为 arithmetic::sin.

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.

用标准(C++11 17.6.1.2/4)的话来说:

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

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

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天全站免登陆