【问题标题】:cmath header confusioncmath 标头混淆
【发布时间】:2011-09-07 02:41:30
【问题描述】:

数学函数的命名空间是什么?全球或std

考虑cos 函数。它有 3 个重载。但也有来自 math.h 的遗留 cos。 C 对函数重载一无所知。因此cos(x) 无法解析为cos(float)。解决方案是显式调用单精度版本cosf(x)。我错过了什么吗?

【问题讨论】:

    标签: c++


    【解决方案1】:

    在 C++ 中包含 <math.c><cmath> 可以获得相同的功能,唯一的区别是命名空间。 IE。包括<math.h> 也会给你带来负担。

    理论上,在 C++03 中,使用 <math.h> 为您提供在全局命名空间和 std 命名空间中定义的符号,而使用 <cmath> 为您提供定义在 std 命名空间而不是全局命名空间中的符号命名空间。

    实践不同,C++ 0X 将理论与实践相结合。 <math.h> 为您提供在全局命名空间中定义的符号,也可能在 std 命名空间中定义,而使用 <cmath> 为您提供在 std 命名空间中定义的符号,也可能在全局命名空间中定义。

    【讨论】:

    • 实际上,03 标准也没有明确禁止 cmath 将内容放入全局命名空间,而新的 0x 标准明确允许这样做就证明了这一点。
    • @paxdiablo,看看open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#206,看来我对 C++03 确实错了。但在相反的方向,它甚至比我更严格。我正在更新我的答案。
    • 我记得 C++03 中的 intent 是,<cfoo> 头文件不应该放在全局命名空间中;然而,即使在您认为每个人都在合作的情况下(例如 gcc 和 glibc),这也被证明是非常难以实现的,而且对于使用标头的人来说也比它真正值得的麻烦更多。我喜欢 C++0x 对此有所退让。
    • @AProg,我很困惑。该链接的第 206 点与不同 new 运营商之间可能存在的差异有关。这两种类型的标头与命名空间填充有何关系?而且我认为第二段仍然不太正确 - C++03 中没有任何内容表明 cmath 不允许 将事物放置在全局命名空间中。它只是声明它填充 std 并将其保留。
    【解决方案2】:

    它们位于std 命名空间中。但是,出于向后兼容的原因,cmath 标头也会在全局命名空间中使用using std::cos; 显示它们。

    【讨论】:

      【解决方案3】:

      cXXX 标头将其所有内容放在 std 命名空间中。他们可能也将它们放在全局命名空间中,但这不是必需的。

      这是来自 C++0x,即将发布的标准,第 D.7 节:

      2/ 每个 C 标头都有一个 name.h 形式的名称,其行为就像每个由相应 cname 标头放置在标准库名称空间中的名称都放置在全局名称空间范围内一样。未指定这些名称是否首先在命名空间 std 的命名空间范围 (3.3.6) 内声明或定义,然后通过显式使用声明 (7.3.3) 注入全局命名空间范围。

      3/ [ 示例:标题<cstdlib> 确实在命名空间std 中提供了它的声明和定义。它还可以在全局命名空间中提供这些名称。标题<stdlib.h> 确实在全局命名空间中提供了相同的声明和定义,就像在 C 标准中一样。它还可以在命名空间std 中提供这些名称。 ——结束示例]

      这与 C++03 的 D.5 节没有变化(在较新的标准中更加明确,但效果相同):

      2/ 每个 C 头文件,每个头文件都有一个 name.h 形式的名称,其行为就像每个由相应 cname 头文件放置在标准库命名空间中的名称也放置在命名空间的命名空间范围内std 后跟一个显式的 using 声明。

      3/ [示例:标题<cstdlib> 在命名空间std 中提供其声明和定义。标题<stdlib.h> 使它们在全局命名空间中也可用,就像在 C 标准中一样。 ——结束示例]

      如果您包含“旧式”XXX.h 标头,则它会放置在两个命名空间中(在标准的两个迭代中)。

      【讨论】:

      • 问题标记为 c++ 而不是 c++0x
      • @Jay:很快,不会有太大区别。
      • @Jay - 这里的 C++0x 仅仅记录了几乎所有 C++ 编译器是如何工作的。在实践中没有区别。
      • 所以编译器开关什么都不做? gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html 我想改变标准的不同实现级别也不需要任何思考?
      • @DeadMG:所以我猜所有遗留代码都会消失,没有人需要维护它?
      【解决方案4】:

      如果您使用的是 C++,则可以依赖函数重载。

      cos一共有三个版本:

      double cos (      double x );
      float cos (       float x );
      long double cos ( long double x );
      

      但是如果你只使用 C 或者你想要可移植性,那么只有这个函数的双重版本存在这个名称。浮点函数是cosf。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-22
        • 1970-01-01
        • 2021-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多