Возможные проблемы с NOMINMAX на Visual С++
Какие проблемы могут возникнуть при определении NOMINMAX
перед чем-либо еще в моей программе?
Насколько я знаю, это сделает <Windows.h>
не определять макросы min
и max
, так что многие конфликты с STL, например, std::min()
, std::max()
или std::numeric_limits<T>::min()
разрешены.
Действительно ли я в предположении, что только у Windows-специфического и устаревшего кода будут проблемы?
Почти все библиотеки не должны зависеть от min()
и max()
, определенных как макросы?
Изменить: Будут ли проблемы с другими заголовками Windows?
Ответы
Ответ 1
Использование NOMINMAX
- единственный не совсем злой способ включить <windows.h>
. Вы также должны определить UNICODE
и STRICT
. Хотя последний определяется по умолчанию современными реализациями.
Однако вы можете столкнуться с проблемами с заголовками Microsoft & ss; s, например. для GdiPlus. Я не знаю о проблемах с заголовками от других компаний или лиц.
Если заголовок определяет пространство имен, как это делает GdiPlus, тогда одно исправление должно создать оболочку для соответствующего заголовка, где вы включаете <algorithm>
и внутри пространства имен заголовка, using namespace std;
(или, альтернативно, и using std::max
):
#define NOMINMAX
#include <algorithm>
namespace Gdiplus
{
using std::min;
using std::max;
}
Обратите внимание, что это очень отличается от using namespace std;
в глобальной области заголовка, что никогда не должно выполняться.
Я не знаю о любом хорошем обходном пути для случая, когда нет пространства имен, но, к счастью, я haven & rsquo; t работает в этом, поэтому на практике эта конкретная проблема, вероятно, спорна.
Ответ 2
Обычно я использую NOMINMAX
для ограничения потенциальных побочных эффектов:
#define NOMINMAX
#include <windows.h>
#undef NOMINMAX
Таким образом, область действия NOMINMAX
относительно ограничена.
Это не идеальное решение. Если что-то еще уже определено NOMINMAX
, этот шаблон не работает (хотя я никогда не встречал такого случая).
Если вы хотите быть действительно, очень осторожны, тогда вы можете # включить заголовок обертки, где бы вы ни были #included windows.h. Обертка будет выглядеть примерно так:
/* Include this file instead of including <windows.h> directly. */
#ifdef NOMINMAX
#include <windows.h>
#else
#define NOMINMAX
#include <windows.h>
#undef NOMINMAX
#endif
Вы могли бы представить себе и другие вещи в оболочке, например, принудительное выполнение UNICODE
и/или STRICT
.
Ответ 3
Для предварительно скомпилированного заголовка (например, stdafx.h) я использую это:
#define NOMINMAX
#include <algorithm>
#include <Windows.h>
#ifndef min
#define min(x,y) ((x) < (y) ? (x) : (y))
#endif
#ifndef max
#define max(x,y) ((x) > (y) ? (x) : (y))
#endif
#include <gdiplus.h>
#undef min
#undef max
Ответ 4
У меня проблема с исправлением, объявив заголовки и пространства имен в следующем порядке:
#include <windows.h>
#include <minmax.h>
#include <gdiplus.h>
using namespace Gdiplus;
using namespace std;