предупреждение C4003 и ошибки C2589 и C2059 на: x = std::numeric_limits‹int›::max();

Эта строка работает правильно в небольшой тестовой программе, но в программе, для которой я ее хочу, я получаю следующие жалобы компилятора:

#include <limits>

x = std::numeric_limits<int>::max();

c:\...\x.cpp(192) : warning C4003: not enough actual parameters for macro 'max'
c:\...\x.cpp(192) : error C2589: '(' : illegal token on right side of '::'
c:\...\x.cpp(192) : error C2059: syntax error : '::'

Я получаю те же результаты с:

#include <limits>
using namespace std;

x = numeric_limits<int>::max();

Почему он видит max как макрос max(a,b); ?


person Harvey    schedule 15.12.2009    source источник
comment
В моем случае без -DNOMINMAX я получал внутреннюю ошибку компилятора. Забавно наблюдать, как Microsoft постоянно борется сама с собой.   -  person rr-    schedule 16.01.2016


Ответы (6)


Обычно это происходит при включении заголовка Windows, определяющего макрос min или max. Если вы используете заголовки Windows, поместите #define NOMINMAX в код или выполните сборку с эквивалентным параметром компилятора (например, используйте /DNOMINMAX для Visual Studio).

Обратите внимание, что сборка с NOMINMAX отключает использование макроса во всей вашей программе. Если вам нужно использовать операции min или max, используйте std::min() или std::max() из заголовка <algorithm>.

person Steve Guidi    schedule 15.12.2009
comment
Хорошо, я просто должен спросить... Могу ли я иметь оба в одном файле? x = std::numeric_limits‹int›::max(); // какая-то хитрая команда препроцессора c = max(a,b); - person Harvey; 15.12.2009
comment
@Harvey: я отредактировал свой ответ, чтобы учесть использование вами max() и макроса max() в одном файле. - person Steve Guidi; 15.12.2009
comment
Я использую min() и max() в других файлах в этом проекте и, используя предварительно скомпилированные заголовки, отключаю их для всех файлов. #undef max работает в моем случае и действует только для остальной части файла, в котором он находится. - person Harvey; 15.12.2009
comment
@Harvey: #undef влияет на остальную часть всей единицы перевода (сильно отличающуюся от остальной части файла, в котором она находится), может привести к результатам, сильно зависящим от порядка включения, и может мешать предварительно скомпилированным заголовкам. Этот ответ является предпочтительным решением. Макросы, такие как min и max, вызывают сложные проблемы, которые должны быть простыми. Макросы - это зло в C++. - person ; 22.02.2010

Другим решением было бы заключить имя функции в круглые скобки следующим образом: (std::numeric_limits<int>::max)(). То же самое относится и к std::max.

Не уверен, что это хорошее решение для этого ... NOMINMAX лучше IMO, но в некоторых случаях это может быть вариантом.

person denis-bu    schedule 26.11.2012
comment
Как бы я ни ненавидел использование глобальных макросов min/max, иногда бывает сложно полностью удалить их из проекта. Никогда не думал об этом как о решении, поэтому +1. - person icabod; 08.10.2013
comment
К сожалению, макросы min и max широко используются в Windows Platform SDK (например, в GDI+ GdiplusTypes.h). Итак, вы лучше отвечаете, чем определяете NOMINMAX. +1! - person 23W; 27.01.2014
comment
Как здесь помогает обертывание? действительно запутался, не могли бы вы немного объяснить? - person Yousuf Azad; 23.08.2016
comment
@ sami1592, очевидно, препроцессор не распознает ...max)() как макросы. Затем (std::numeric_limits<int>::max) преобразуется в указатель функции, а () — это вызов функции, вызываемый для указателя функции. Вы можете использовать отладчик, чтобы проверить это. Просто введите auto fp = (std::numeric_limits<int>::max); и проверьте тип fp во время выполнения. - person denis-bu; 25.08.2016

Какой-то другой заголовочный файл загрязняет глобальное пространство имен макросом max. Вы можете исправить это, отменив определение макроса:

#undef max
x = std::numeric_limits<int>::max();
person R Samuel Klatchko    schedule 15.12.2009
comment
Не исправляйте это таким образом, вы можете предотвратить его определение в первую очередь с помощью NOMINMAX. - person GManNickG; 16.10.2013

Его определение для меня в Visual Studio 2013 (отформатированное для лучшего интервала...) выглядит следующим образом:

static _Ty (max)() _THROW0()
{   // return maximum value
    return (FLT_MAX);
}

Так что я просто использую FLT_MAX. :) Возможно, это не универсальное решение, но в моем случае оно работает хорошо, поэтому решил поделиться.

person Andrew    schedule 15.05.2015
comment
Будьте осторожны, вам (может быть) понадобится #include <float.h> для доступа к FLT_MAX - person Ben Voigt; 16.05.2015

(стандартное::numeric_limits::max)()

Проще простого.

person Mattias Bergmark    schedule 10.04.2019

person    schedule
comment
@MattMcNabb Я изменил это - person dmjalund; 27.01.2015