"numeric_limits"在此范围内未声明,调用'max()'函数没有匹配项。

42

我在家用Xcode编译这个代码时没有问题,但在学校用Linux上的g++编译时出现了以下错误:

‘numeric_limits’不是std的成员

在“>”标记之前期望主表达式

没有找到匹配的max()函数

#include <iostream>
#include <cstdlib>

using namespace std;

int GetIntegerInput(int lower, int upper)
{
    int integer = -1;
    do
    {
        cin >> integer;
        cin.clear();
        cin.ignore(std::numeric_limits<streamsize>::max(), '\n');  //errors here
    } while (integer < lower || integer > upper);

    return integer;
}
我猜可能需要包含一个额外的头文件。如果我去掉 std::,它只会给我一个类似的错误:numeric_limits was not declared in this scope。

当你阅读 numeric_limits 的文档以了解如何使用它时,它没有告诉你它所在的头文件是什么吗? - Rob Kennedy
是的,但那是一段时间之前的事情了,然后我最近才意识到从我的另一个项目中复制粘贴了代码。 - Matt Munson
添加 #include <limits> - Milovan Tomašević
2个回答

80

你需要包含头文件<limits>std::numeric_limits就是在其中定义的。你的Mac编译器会自动帮你包含这个头文件,但是你不应该依赖这个行为,要明确地包含所有需要的头文件。


10
这个特性有一个名称吗?我想找出如何禁用它,以便不破坏平台独立性。 - MatrixManAtYrService

12
GCC 11开始明确要求包含<limits><memory><utility><thread>,请参考https://www.gnu.org/software/gcc/gcc-11/porting_to.html#header-dep-changes
Clang 12(或更早版本)也有类似的情况,我不确定。
由于我经常在使用Node.js的软件包管理器yarn时遇到这个错误,它会覆盖所有源文件,因此我无法轻松添加#include <limits>:我需要分叉或者在编译过程中不断地运行cp /tmp/fixedBad.h /installdir/bad.h
因此,我的解决方案是将以下代码添加到CXXFLAGS(而不是CFLAGS)中: -include /usr/include/c++/11/limits(Ubuntu 21.04,gcc 11.1.0) -include /usr/include/c++/11.1.0/limits(Arch Linux;版本相同,但路径与Debian / Ubuntu不同)
或优雅地: -include /usr/include/c++/11*/limits 请注意,只有在shell(bash、sh、zsh等)或makefile中使用*才有效。换句话说,gcc和clang不会注意文件路径中的*,因此如果您使用ninja build或直接从C程序传递参数给gcc / clang,请注意。
我将这个设置添加到了/etc/environment中。
#CPPFLAGS="-D_FORTIFY_SOURCE=2 -DNDEBUG"
CPPFLAGS="-D_FORTIFY_SOURCE=2"
CFLAGS="-g -pipe -march=native -mtune=native -Ofast -pipe -ftree-vectorize -fstack-protector-strong"
CXXFLAGS="-g -pipe -march=native -mtune=native -Ofast -pipe -ftree-vectorize -fstack-protector-strong -include /usr/include/c++/11*/limits"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro"
RUSTFLAGS="-C target-cpu=native -C opt-level=2"

请检查echo $CXXFLAGS,如果更改未生效,请重新启动shell或操作系统,或注销当前tty,或切换到另一个tty,或在终端中运行:

export CXXFLAGS="-g -pipe -march=native -mtune=native -Ofast -pipe -ftree-vectorize -fstack-protector-strong -include /usr/include/c++/11*/limits"

或者使用 set -a; source /etc/environment; set +a;

我还尝试将-include '<limits>'-include '<limits.h>'添加到CXXFLAGS中,但它会显示“没有这个文件或目录”

此外,我还有另一个解决方案(非常粗糙):

在最后一行 (#endif) 之前将以下内容添加到 /usr/include/stdint.h (或 stdlib.h 或其他一些流行的文件) 中:

#ifdef __cplusplus
extern "C++" {
       #include <limits>
}
#endif

Ubuntu 21.04和Debian Buster的dpkg-query -S /usr/include/stdlib.h显示它是由libc6-dev:amd64拥有。而Arch Linux的pacman -Qo /usr/include/stdlib.h显示它是由glibc拥有。因此,在软件包更新时,这个hack将被覆盖,请不要忘记。


1
似乎-include limits-includelimits都能起作用。 - Nemo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接