NOMINMAX
をプログラムで他の何よりも先に定義すると、どのような問題が発生しますか?
私の知る限り、これにより_<Windows.h>
_はmin
およびmax
マクロを定義せず、STLとの多くの競合が発生します。 std::min()
、std::max()
、またはstd::numeric_limits<T>::min()
は解決されます。
Windows固有のレガシーコードのみに問題があるという前提で正しいのでしょうか。ほとんどすべてのライブラリは、マクロとして定義されているmin()
およびmax()
に依存するべきではありませんか?
編集:他のWindowsヘッダーに問題はありますか?
NOMINMAX
を使用することは、<windows.h>
をインクルードするための唯一の完全ではない方法です。 UNICODE
とSTRICT
も定義する必要があります。後者は最近の実装ではデフォルトで定義されていますが。
ただし、Microsoftのヘッダーに問題が発生する可能性があります。 GdiPlusの場合。他の会社や個人のヘッダーの問題は知りません。
ヘッダーがGdiPlusのように名前空間を定義する場合、1つの修正は、関連するヘッダーのラッパーを作成することです。この場合、<algorithm>
を含み、ヘッダーの名前空間内にusing namespace std;
(またはusing std::min;
およびusing std::max
):
#define NOMINMAX
#include <algorithm>
namespace Gdiplus
{
using std::min;
using std::max;
}
これは、ヘッダーのグローバルスコープでのusing namespace std;
とは大きく異なります。これはnever doにする必要があります。
名前空間がない場合の適切な回避策はわかりませんが、幸いにもそれに遭遇していないので、実際にはその特定の問題はおそらく疑わしいものです。
潜在的な副作用を制限するために、私は通常、次のようにNOMINMAX
を使用します。
#define NOMINMAX
#include <windows.h>
#undef NOMINMAX
このようにして、NOMINMAX
のスコープは比較的限定されます。
それは完璧な解決策ではありません。他にNOMINMAX
がすでに定義されている場合、このパターンは失敗します(私はそのようなケースに遭遇したことはありません)。
本当に、本当に慎重になりたい場合は、#includeされたwindows.hがある場所に#includeラッパーヘッダーを含めることができます。ラッパーは次のようになります。
/* 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
を強制するなど、ラッパーで他のことを行うことも想像できます。
プリコンパイル済みヘッダー(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
ヘッダーと名前空間を次の順序で宣言することで問題を修正しました。
#include <windows.h>
#include <minmax.h>
#include <gdiplus.h>
using namespace Gdiplus;
using namespace std;