2012-07-18 13 views
31

私はcinから有効な整数の入力を取得しようとしていましたが、この回答はquestionでした。windows.hのmaxマクロをstdのmaxと衝突させるにはどうすればいいですか?

それは推奨:

#include <Windows.h> // includes WinDef.h which defines min() max() 
#include <iostream> 
using std::cin; 
using std::cout; 

void Foo() 
{ 
    int delay = 0; 
    do 
    { 
     if(cin.fail()) 
     { 
      cin.clear(); 
      cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
     } 
     cout << "Enter number of seconds between submissions: "; 
    } while(!(cin >> delay) || delay == 0); 
} 

maxマクロは、多くの引数を取らないことを言って、私はWindows上でエラーを与えます。これは私がこれをしなければならないことを意味する

do 
{ 
    if(cin.fail()) 
    { 
     cin.clear(); 
#undef max 
     cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    } 
    cout << "Enter number of seconds between submissions: "; 
} while(!(cin >> delay) || delay == 0); 

それを動作させるには。それはかなり醜いです。この問題を回避するより良い方法はありますか?たぶん私はmaxの定義を保存して、それを後で再定義する必要がありますか?

+3

をあなたはが含まれていますか?どうして?本当に必要な場合は、** NOMINMAX **を定義することで_min_と_max_マクロの定義を避けることができます。 –

+1

"namespace std"を使用していますか?その場合、意図的に名前空間を結合しています。 –

+4

@PaulBeckingham:マクロに名前空間がないため、注意を払わずにwindows.hを含めても常に 'std :: min' /' std :: max'と衝突します – PlasmaHH

答えて

64

は、マクロNOMINMAXを定義します。

これはWindef.hでの最小値と最大値の定義を抑制します。

8

あなたは単にcinバッファをフラッシュしようとしていますか?私はいつもちょうど使用:

cin.ignore(cin.rdbuf()->in_avail()); 
+0

これは良い答えですが、私はもう一方の質問に直接答える一方、あなたの回答は問題の原因を別の方法で解決します。 :) – Almo

6

あなたは他の誰かがNOMINMAXなしwindows.hが含まれている可能性があるかどうかわからない場合、あなたは定義を変更することなく、関数のようなマクロ呼び出しを抑制するために用いることができるダミーのマクロを定義できます。

#define DUMMY 
... 
std::numeric_limits<std::streamsize>::max DUMMY() 

本当にかわいいですが、動作し、非侵入型です。

Windowsヘッダーファイルを扱う際には、あまりにも多くのゴミをグローバル名前空間に投げ込むので、特殊なコードとヘッダーファイル(必要に応じてpimplを使用する)にだけ含めることでできるだけ隠すことを好みます。

(std::numeric_limits<size_type>::max)() 

この場合NOMINMAXマクロの不要を、プラスあなたがGDI +を使用することが起こる場合は、コンパイラの警告に、アプローチを

+2

面白いです。私は間違いなくwindows.hを可能な限り切り離すための助言に従います。 – Almo

32

ただ、カッコ内に関数名をラップNOMINMAXを使用すると、GDI +のヘッダーにはグローバル名前空間にminまたはmaxが必要なため、うまく動作しません。

この場合の最も簡単な回避策は、不要になったときにmin/maxを未定義にすることです。

アプローチ説明するためのサンプルコード:

//#define NOMINMAX - this won't work 
#include <Windows.h> 
#include <gdiplus.h> 
#undef max 
#undef min 
... 
#include <cxxopts.hpp> 
+0

'std :: max (a、b)'は私にとってはうまく動作し、読みやすくなっています。テンプレートパラメータは、マクロを抑制します。何か不足していますか? –

+0

@DaleWilsonはい、何か不足しています。あなたの呼び出しは2つの値のうち大きい方を取得します。 std :: numeric_limits :: max()は、size_typeで格納できる最大値を返します。 – Ben

+1

関数名を括弧で囲んでいるのは、関数ポインタを使って戦略パターンを実装しているかのように関数ポインタを呼び出すことです。これは、[コードでアイデアを直接表現する](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#p1-express-ideas-directly-in-code)のアドバイスに反するむしろmin&maxマクロの定義を回避する試み(関数ポインタによる戦略パターンの実装ではない)です。 Clang/LLVMインフラストラクチャは、 "#define NOMINMAX'をWindowsヘッダの前に"示唆しています "。どちらがより良い助言IMOです。 –

1

を得ることはありません。

+0

しかし、潜在的に問題を逆転させます:ヘッダーで名前の衝突が発生し、ここで説明したように解決され、このヘッダーをmin/maxをまだ定義していない場所に含めると - 不運 – Aconcagua

関連する問題