std :: min дает ошибку - PullRequest
       3

std :: min дает ошибку

94 голосов
/ 15 февраля 2011
#include <algorithm>
#include <Windows.h>

int main()
{
    int k = std::min(3, 4);
    return 0;
}

Что делает Windows, если я включаю Windows.h, я не могу использовать std :: min в visual studio 2005. Сообщение об ошибке:

error C2589: '(' : illegal token on right side of '::'
error C2059: syntax error : '::'

Ответы [ 10 ]

138 голосов
/ 15 февраля 2011

Заголовочный файл windows.h (или, точнее, windef.h, который он включает в себя) содержит макросы для min и max, которые мешают.

Вы должны #define NOMINMAX перед включениемэто.

73 голосов
/ 25 февраля 2014

Не нужно ничего определять, просто обойти макрос, используя этот синтаксис:

(std::min)(a, b); // added parentheses around function name
(std::max)(a, b);
22 голосов
/ 15 февраля 2011

Как уже упоминалось, ошибки происходят из-за макросов min / max, которые определены в заголовках окна.Есть три способа их отключения.

1) #define NOMINMAX перед включением заголовка, как правило, это плохой метод определения макросов для воздействия на следующие заголовки:

2) define NOMINMAX в командной строке компилятора / IDE.Плохая часть этого решения заключается в том, что если вы хотите отправить свои исходники, вы должны предупредить пользователей о том, чтобы они делали то же самое;

3) просто отменяют определение макросов в вашем коде, прежде чем они будут использованы

#undef min
#undef max

Это, пожалуй, самое портативное и гибкое решение.

17 голосов
/ 18 июня 2015

У меня иногда возникают проблемы с заголовками окон, и определение NOMINMAX в рамках проекта не всегда работает. В качестве альтернативы использованию скобок, я иногда делаю тип явным образом так:

int k = std::min<int>(3, 4);

Это также останавливает сопоставление препроцессора с min и, возможно, более читабельно, чем обходной путь в скобках.

15 голосов
/ 15 февраля 2011

Попробуйте что-то вроде этого:

#define NOMINMAX
#include <windows.h>

По умолчанию windows.h определяет min и max как макросы. Когда они расширены, код, который пытается использовать std::min (например), в конечном итоге будет выглядеть примерно так:

int k = std::(x) < (y) ? (x) : (y);

Сообщение об ошибке сообщает, что std::(x) не разрешено.

4 голосов
/ 22 ноября 2014

В моем случае проект явно не включал windows.h или windef.h.Он использовал Boost.Итак, я решил проблему, перейдя в проект Properties -> C/C++ -> Preprocessor и добавив NOMINMAX в Preprocessor Definitions (VS 2013, VS 2015).

2 голосов
/ 02 октября 2015

Для людей, в том числе windows.h, поместите в соответствующие заголовки следующее:

#include windows headers ...

pragma push_macro("min")
pragma push_macro("max")
#undef min
#undef max

#include headers expecting std::min/std::max ...

...

pragma pop_macro("min")
pragma pop_macro("max")

В исходных файлах просто #undef min и max.

#include windows headers ...

#undef min
#undef max

#include headers expecting std::min/std::max ...
2 голосов
/ 15 февраля 2011
#define NOMINMAX

- это трюк для подавления макроопределений max и min

http://support.microsoft.com/kb/143208

1 голос
/ 15 февраля 2011

Я бы предположил, что windows.h определяет min как макрос, например, как

#define min(a,b)  ((a < b) ? a : b)

Это объясняет сообщение об ошибке.

0 голосов
/ 13 июня 2018

Чтобы решить эту проблему, я просто создаю заголовочный файл с именем fix_minmax.h без , включающий охрану

#ifdef max
    #undef max
#endif

#ifdef min
    #undef min
#endif

#ifdef MAX
    #undef MAX
#endif
#define MAX max

#ifdef MIN
   #undef MIN
#endif
#define MIN min

#include <algorithm>
using std::max;
using std::min;

Основное использование такое.Этот подход заключается в том, что он работает с каждым типом включенного файла или части кода.Это также экономит ваше время при работе с кодом или библиотеками, которые зависят от min / max макросов

...