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


#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 83

10 ответов:

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

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

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

(std::min)(a, b); // added parentheses around function name
(std::max)(a, b);

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

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

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

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

#undef min
#undef max

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

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

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

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

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

#define NOMINMAX
#include <windows.h>

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

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

сообщение об ошибке говорит вам, что std::(x) не допускается.

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

#define NOMINMAX

это трюк, чтобы подавить макроопределения max и min

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

для людей, включая 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 ...

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

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

что бы объяснить сообщение об ошибке.

чтобы решить эту проблему, я просто создаю заголовочный файл с именем 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;

основное использование такой.

// Annoying third party header with min/max macros
#include "microsoft-mega-api.h"
#include "fix_minmax.h"

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