Windows.h eklendiğinde std :: min neden başarısız oluyor?


Yanıtlar:


158

windows.hBaşlık dosyası (ya da daha doğrusu, windef.hbu sırayla içerdiğini) için makroları vardır minvemax hangi engellemesini.

Sen gerektiğini #define NOMINMAXdaha önce dahil.


29
MAKROS'un kötü olmasının nedenlerinden biri. : D
Nawaz

7
Proje çapında / D "NOMINMAX" kullandım
Micka

@Micka: Bu seçeneği proje ayarlarınızın içinde nereye koydunuz? Aynı seçeneği kullanmalıyım ve nereye koyacağımı bilmiyorum ...
flaviu2

@ flaviu2, tüm derleme komutlarının özetlendiği sayfadaki "ek komutlar" alanında afair. Ancak şu anda kontrol edemiyorum
Micka

çünkü eklemekti: #include <algorithm> + NOMINMAX
user63898

92

Hiçbir şey tanımlamanıza gerek yok, sadece bu sözdizimini kullanarak makroyu atlayın:

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

1
Teşekkür ederim, benim için işe yarayan çözüm bu. Kodun bir kısmı Windows'tan makrolara ihtiyaç duyan çizim kodunu kullandığından NOMINMAX'ı basitçe kullanamadığım bir kod üzerinde çalışıyorum.
Mickaël C. Guimarães

1
Büyünün etrafındaki parantezlerin kötü makroyu neden yenebileceğini açıklayabilir misiniz? Cool
Chen OT

2
Kaputun altındaki tüm sihirden tam olarak emin değilim, ancak makro ayrıştırıcının tam olarak "min (", yani "min) (" makro ayrıştırıcısı tarafından göz ardı edildiğine inanıyorum. Ve işlev adı ile sarılmış anlamsız () 's makrolar dışında herhangi bir soruna neden olmaz.
PolyMesh

1
Düzgün bir çözüm, ancak adı minveya max(örnek kullanım durumu: UniformRandomNumberGenerator konseptine uyan bir sınıfın uygulanması) ile bir işleve sahip olma problemini çözmez .
Nik Bougalis

Lütfen Erik'in cevabına bakın, bunun daha iyi bir çözüm olduğunu düşünüyorum. Daha az hack ve daha net.
PolyMesh

28

Diğerlerinde belirtildiği gibi, hatalar Windows başlık (lar) ında tanımlanan min / maks makrolarından kaynaklanmaktadır. Bunları devre dışı bırakmanın üç yolu vardır.

1) #define NOMINMAXbaşlığı eklemeden önce, bu genellikle aşağıdaki başlıkları etkilemek için makroları tanımlamak için kötü bir tekniktir;

2) NOMINMAXderleyici komut satırında / IDE'de tanımlayın . Bu kararın kötü yanı, kaynaklarınızı göndermek istiyorsanız, aynı şeyi yapması için kullanıcıları uyarmalısınız;

3) Kullanılmadan önce kodunuzdaki makroları tanımlamanız yeterli

#undef min
#undef max

Bu muhtemelen en taşınabilir ve esnek çözümdür.


2
1. seçenekle ilgili diğer bir sorun da, her zaman işe yaramamasıdır. Gdiplus.h gibi gerçekten ihtiyaç duyan başka bir yere dahil edilen başka Windows başlıkları olabilir. Bu durumda 3. seçenek tek umudunuz olabilir.
shawn1874

27

Hala ara sıra Windows başlıkları ile sorun yaşıyorum ve NOMINMAX'ın proje geniş tanımlaması her zaman işe yaramıyor gibi görünüyor. Parantez kullanmaya alternatif olarak, bazen türü açık hale getiriyorum:

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

Bu aynı zamanda önişlemcinin eşleşmesini engeller minve muhtemelen parantez geçici çözümünden daha okunabilirdir.


3
Katılıyorum, bu en iyi çözüm. Başka birinin beni dövdüğünü görünce başka bir cevap vermek için geri dönüyordum.
POLYMESH

16

Bunun gibi bir şey dene:

#define NOMINMAX
#include <windows.h>

Windows.h varsayılan olarak minve maxmakroları tanımlar . Bunlar genişletildiğinde, kullanmaya çalışan kod std::min(örneğin) şuna benzer bir şeye bakacaktır:

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

Hata mesajı size std::(x)buna izin verilmediğini söylüyor .


5

Benim durumumda, proje içermiyordu windows.hveya windef.haçıkça. Boost kullanıyordu. Yani, projenin giderek sorunu çözüldü Properties -> C/C++ -> Preprocessorve ekleme NOMINMAXde Preprocessor Definitions(VS 2013 VS 2015).


VS 2015 için dosyadaki makroyu tanımlamak benim için işe yaramadı. Projede tanımlama çalıştı.
qqqqq

3

Windows.h dahil kişiler için, etkilenen başlıklara aşağıdakileri koyun:

#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")

Kaynak dosyalarda sadece #undef min ve maks.

#include windows headers ...

#undef min
#undef max

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


2

Bu sorunu çözmek için fix_minmax.h , dahil etme korumaları içermeyen bir başlık dosyası oluşturuyorum.

#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;

Temel kullanım şu şekildedir.

// Annoying third party header with min/max macros
#include "microsoft-mega-api.h"
#include "fix_minmax.h"

Bu yaklaşımın avantajları, dahil edilen her tür dosya veya kodun parçasıyla çalışmasıdır. Bu ayrıca min/ maxmakrolara bağlı kod veya kitaplıklarla uğraşırken zaman kazandırır.


1

Windows.h'nin min'i bir makro olarak tanımladığını varsayıyorum, örneğin

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

Bu hata mesajını açıklar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.