क्यों std :: windows.h शामिल करते समय मिनट विफल हो रहा है?


107
#include <algorithm>
#include <Windows.h>

int main()
{
    int k = std::min(3, 4);
    return 0;
}

अगर मैं Windows.h को शामिल करता हूँ तो विंडोज़ क्या कर रही है? मैं std::min2005 के दृश्य स्टूडियो में उपयोग नहीं कर सकता । त्रुटि संदेश है:

error C2589: '(' : illegal token on right side of '::'
error C2059: syntax error : '::'

जवाबों:


156

windows.hहेडर फाइल (या अधिक सही ढंग से, windef.hयह है कि यह बदले में भी शामिल है) के लिए मैक्रो है minऔर maxजो दखल दे रहे हैं।

आपको #define NOMINMAXइसे शामिल करने से पहले करना चाहिए ।


27
एमआरआरओएस दुष्टता का एक कारण है। : डी
नवाज

7
मैंने प्रोजेक्ट-वाइड / D "NOMINMAX" का उपयोग किया है
मिका जूल

@ मिक्का: आपने अपनी परियोजना सेटिंग्स के अंदर यह विकल्प कहां रखा था? मुझे एक ही विकल्प का उपयोग करना होगा, और मुझे नहीं पता कि कहां रखा जाए ...
flaviu2

पृष्ठ पर "अतिरिक्त कमांड्स" फ़ील्ड में @ flaviu2 अफेयर, जहां सभी संकलित कमांड संक्षेप हैं। लेकिन इस समय
मिका

इसके लिए जोड़ना था: #include <एल्गोरिथम> + NOMINMAX
user63898

89

कुछ भी परिभाषित करने की आवश्यकता नहीं है, बस इस सिंटैक्स का उपयोग करके मैक्रो को बायपास करें:

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

1
धन्यवाद, यह मेरे लिए काम करने वाला उपाय है। मैं एक ऐसे कोड पर काम कर रहा हूँ जहाँ मैं NOMINMAX का उपयोग नहीं कर सकता हूँ क्योंकि कोड का कुछ हिस्सा विंडोज़ से आरेखण कोड का उपयोग करता है जिसे मैक्रोज़ की आवश्यकता होती है।
मिकाल सी। गुइमारेस

क्या आप बता सकते हैं कि जादू के इर्द-गिर्द कोष्ठक बुराई स्थूल को क्यों हरा सकता है !? कूल
चेन ओटी

1
मुझे हुड के नीचे सभी जादू के बारे में पूरी तरह से यकीन नहीं है, लेकिन मेरा मानना ​​है कि मैक्रो पार्सर बिल्कुल "मिनट (", इसलिए "मिन) (" मैक्रो पार्सर द्वारा अनदेखा किया गया है।) और फ़ंक्शन नाम के साथ लिपटा जा रहा है। अर्थहीन () का मैक्रो के बाहर कोई भी मुद्दा नहीं है।
पॉलीमेश

1
साफ समाधान है, लेकिन नाम के साथ एक समारोह होने की समस्या के लिए समाधान नहीं करता है minया max(: एक वर्ग को लागू करने कि में फिट बैठता है नमूना उपयोग के मामले UniformRandomNumberGenerator अवधारणा)।
निक बुगालिस

कृपया एरिक का जवाब देखें, मुझे लगता है कि यह एक बेहतर समाधान है। कम हैसी, और स्पष्ट।
पॉलीमेश

28

जैसा कि दूसरों ने उल्लेख किया है, त्रुटियां न्यूनतम / अधिकतम मैक्रोज़ के कारण होती हैं जो विंडोज़ हेडर (एस) में परिभाषित होती हैं। उन्हें अक्षम करने के तीन तरीके हैं।

1) #define NOMINMAXहेडर को शामिल करने से पहले, यह आम तौर पर निम्न हेडर को प्रभावित करने के लिए मैक्रोज़ को परिभाषित करने की एक खराब तकनीक है;

2) NOMINMAXकंपाइलर कमांड लाइन / आईडीई में परिभाषित । इस निर्णय के बारे में बुरा हिस्सा यह है कि यदि आप अपने स्रोतों को भेजना चाहते हैं, तो आपको उपयोगकर्ताओं को ऐसा करने की चेतावनी देने की आवश्यकता है;

3) बस अपने कोड में मैक्रोज़ का उपयोग करने से पहले उन्हें अपरिभाषित करें

#undef min
#undef max

यह शायद सबसे पोर्टेबल और लचीला समाधान है।


2
विकल्प 1 के साथ एक और मुद्दा यह है कि यह हमेशा काम नहीं करता है। अन्य विंडोज़ हेडर कहीं और शामिल हो सकते हैं जो वास्तव में इसकी आवश्यकता होती है जैसे कि gdiplus.h। उस स्थिति में विकल्प 3 आपकी एकमात्र आशा हो सकती है।
shawn1874

27

मुझे अभी भी कभी-कभार परेशानी होती है कि विंडोज़ हेडर और NOMINMAX की विस्तृत परिभाषा हमेशा काम नहीं करती। कोष्ठक का उपयोग करने के लिए एक विकल्प के रूप में, मैं कभी-कभी प्रकार को स्पष्ट करता हूं:

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

यह प्रीप्रोसेसर को मिलान करने से भी रोकता है minऔर यकीनन कोष्ठक वर्कअराउंड की तुलना में अधिक पठनीय है।


3
मैं सहमत हूं, यह सबसे अच्छा समाधान है। मैं अभी एक और जवाब देने के लिए वापस आ रहा था जब मैंने देखा कि किसी और ने मुझे इसे पीटा है।
पॉलीमेश

16

कुछ इस तरह की कोशिश करो:

#define NOMINMAX
#include <windows.h>

डिफ़ॉल्ट रूप से, windows.h परिभाषित करता है minऔर maxमैक्रोज़ के रूप में। जब उन का विस्तार किया जाता है, तो कोड जो उपयोग करने की कोशिश करता है std::min(उदाहरण के लिए) कुछ इस तरह दिखाई देगा:

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

त्रुटि संदेश आपको बता रहा है कि std::(x)अनुमति नहीं है।


5

मेरे मामले में, परियोजना में शामिल windows.hया windef.hस्पष्ट रूप से शामिल नहीं था । यह बूस्ट का उपयोग कर रहा था। तो, मैं इस परियोजना के लिए जा रहा द्वारा इस मुद्दे को हल Properties -> C/C++ -> Preprocessorहै, और जोड़कर NOMINMAXमें Preprocessor Definitions(वी.एस. 2013 वी.एस. 2015)।


वीएस 2015 के लिए फ़ाइल में मैक्रो को परिभाषित करना मेरे लिए काम नहीं करता था। परियोजना में परिभाषित करने से काम हुआ।
qqqqq

3

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 मिनट और अधिकतम।

#include windows headers ...

#undef min
#undef max

#include headers expecting std::min/std::max ...


2

इस समस्या को हल करने के लिए मैं सिर्फ हेडर फ़ाइल बनाता हूं, जिसमें 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मैक्रोज़ पर निर्भर करते हैं


1

मुझे लगता है कि windows.h एक स्थूल, जैसे जैसे न्यूनतम परिभाषित करता है

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

यह त्रुटि संदेश की व्याख्या करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.