Подтвердить что ты не робот

Почему происходит сбой std::min, когда включен windows.h?

#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 : '::'
4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

Как упоминалось выше, ошибки связаны с макросами min/max, которые определены в заголовках (окнах) Windows. Существует три способа их отключения.

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

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

3) просто отмените определение макросов в коде перед их использованием.

#undef min
#undef max

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

Ответ 4

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

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

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

Ответ 5

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

#define NOMINMAX
#include <windows.h>

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

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

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

Ответ 6

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

Ответ 8

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

Ответ 9

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

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

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

Ответ 10

Для меня работает следующее.

using namespace std;
int k = min(3, 4);

Ответ 11

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