为什么我不能在 C++ 中定义“epsilon”后包含标准算法库?

rvv*_*len 8 c++ algorithm macros epsilon c++-standard-library

当我在定义 epsilon 之前包含算法库时,会编译以下代码:

#include <iostream>
#include <algorithm>

#define epsilon 0.00001

int main() {
    std::cout << epsilon; 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我切换它们时,它不会:

#include <iostream>

#define epsilon 0.00001

#include <algorithm>

int main() {
    std::cout << epsilon; 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它给出了以下错误 19 次:

epsilon_algorithm.cpp:3:17: error: expected unqualified-id before numeric constant
    3 | #define epsilon 0.00001
      |
Run Code Online (Sandbox Code Playgroud)

http://www.cplusplus.com/reference/algorithm/https://en.cppreference.com/w/cpp/algorithm上没有提到任何名为“epsilon”的东西。我知道我可以通过在定义 epsilon 之前简单地始终包含 <algorithm> 来避免这个问题,我想知道是什么导致了这个错误,以扩大我对 C++ 的理解并防止将来出现这些类型的错误。

我在更新的 Windows 10(64 位)环境中使用 MinGW(32 位,几周前安装)进行编译。

Yks*_*nen 14

允许标准库头文件包含任何其他标准库头文件。

有可能<algorithm>包括<limits>并且存在std::numeric_limits::epsilon()那里。当然,宏会忽略命名空间和类,因此它会尝试声明一个名为0.00001.

不要使用宏。使用 C++ 常量:

constexpr double epsilon = 0.00001;
Run Code Online (Sandbox Code Playgroud)

如果您绝对需要宏,请始终包含之后定义它们。之前定义它们会使您的代码非常脆弱 - 将来这些标头中的任何更改都可能会因神秘的编译器错误而炸毁您的代码。
出于同样的原因,不要在头文件中定义宏。
尽可能使用非常本地化的宏 - 在需要的地方和#undef完成后定义它们。这样它们就不会泄漏到外面(尽管您仍然可以无意中覆盖现有的宏)。