为什么abs不在std中?

#include <cmath>
int abs;
int main()
{

}

此代码引发编译错误

error: 'int abs' redeclared as different kind of symbol
note: previous declaration 'int abs(int)'

如果我从cstdlib.

我阅读了这个文档https://en.cppreference.com/w/cpp/numeric/math/abs
其中没有提到abs将在std. 事实上,它明确提到它std::abs无处不在。

其他函数也会发生同样的事情,例如sqrt.

为什么会这样?如何在不弄乱我的命名空间的情况下使用这些函数?如果不可能,是否有 C++ 替代方案?

回答

为什么 abs 不在 std 中?

你的问题有点不对。abs std。让我假设您问“为什么 abs也在全局命名空间中?” .

除了在命名空间中声明之外,C++ 标准还允许在全局命名空间中声明 C 标准函数std

为什么会这样?

因为这些函数来自 C 标准库,并且因为标准允许它发生,并且因为您的标准库的实现方式。

如何在不弄乱命名空间的情况下使用这些函数?

这些名称保留给全局命名空间中的语言实现。没有办法避免它。

不要将全局命名空间视为“您的命名空间”。全局命名空间很混乱,而且总是如此。你需要解决这个问题。

如果不可能,是否有 C++ 替代方案?

C++ 的替代方法是在您的命名空间中声明 abs

namespace my_very_own_namespace {
    int abs;
}

您应该在自己的命名空间中声明所有内容1,除了:

  • 该命名空间本身
  • main
  • 允许的其他命名空间中名称的模板特化
  • 跨语言 API,即任何东西 extern "C"

最困难的部分是为您自己的命名空间找出一个唯一的名称,因为它不能是 C 标准库已经使用的名称,也不能是全局命名空间中其他库使用的任何名称。

1在编写小型练习程序等时,遵循这条经验法则几乎没有必要。但在编写大型程序和依赖第三方库时,它变得必不可少,更不用说编写这些库供他人使用时了。


标准报价:

[外部名称]

使用外部链接声明的 C 标准库中的每个名称都保留给实现用作具有外部“C”链接的名称,在命名空间 std 和全局命名空间中。

使用外部链接声明的 C 标准库中的每个函数签名都保留给实现,以用作具有 extern "C" 和 extern "C++" 链接的函数签名,171 或用作全局命名空间中的命名空间范围的名称。

[标题]

除了在[library]到[thread]和[depr]中注明外,每个头文件cname的内容与C标准库中指定的对应头文件name.h的内容相同。但是,在 C++ 标准库中,声明(在 C 中定义为宏的名称除外)在命名空间 std 的命名空间范围内。未指定这些名称(包括通过 [thread] 和 [depr] 添加到 [support] 中的任何重载)是否首先在全局命名空间范围内声明,然后通过显式 using 声明([namespace.udecl])注入到命名空间 std 中)。


以上是为什么abs不在std中?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>