Why are some functions in lt;cmathgt; not in the std namespace?(为什么lt;cmathgt;中有一些函数不在 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:
mathcalls.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).
这篇关于为什么<cmath>中有一些函数不在 std 命名空间中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么<cmath>中有一些函数不在 std 命名空间中?
基础教程推荐
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- CString 到 char* 2021-01-01
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 初始化列表*参数*评估顺序 2021-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
