windows.h가 포함되어 있는데 std :: min이 실패하는 이유는 무엇입니까?


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

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

Windows.h를 포함하면 Windows는 무엇을합니까? std::minVisual Studio 2005에서 사용할 수 없습니다 . 오류 메시지는 다음과 같습니다.

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

답변:


156

windows.h헤더 파일 (또는 더 정확하게, windef.h이 차례로 포함)을위한 매크로가 min하고 max있는 간섭있다.

#define NOMINMAX포함하기 전에 해야 합니다.


27
매크로가 나쁜 이유 중 하나입니다. : D
Nawaz

7
나는 프로젝트 전체 / D "NOMINMAX"사용했습니다
Micka

@Micka : 프로젝트 설정에서이 옵션을 어디에 넣었습니까? 나도 같은 옵션을 사용해야하고, 내가 넣어 위치를 모르는 ...
flaviu2

모든 컴파일 명령이 요약 된 페이지의 "추가 명령"필드에서 @ flaviu2 afair. 그러나 순간에 확인할 수 없습니다
Micka

그것을 추가하기 위해 : #include <algorithm> + NOMINMAX
user63898 nov.

90

아무것도 정의 할 필요가 없습니다. 다음 구문을 사용하여 매크로를 우회하면됩니다.

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

1
감사합니다. 이것이 저에게 도움이 된 솔루션입니다. 코드의 일부가 매크로가 필요한 Windows의 그리기 코드를 사용하기 때문에 단순히 NOMINMAX를 사용할 수없는 코드를 작업 중입니다.
Mickaël C. Guimarães 2015 년

마법 주위의 괄호가 왜 사악한 매크로를 이길 수 있는지 설명해 주시겠습니까!? 쿨
첸 OT에게

1
내부의 모든 마법에 대해 완전히 확신 할 수는 없지만 매크로 파서가 정확히 "min ("을 대체하려고하므로 "min) ("은 매크로 파서에 의해 무시됩니다. (가)의 의미는 매크로 아닌 문제 원인 외부한다.
폴리 메쉬

1
깔끔한 솔루션이지만 이름이있는 함수 min또는 max(샘플 사용 사례 : UniformRandomNumberGenerator 개념에 맞는 클래스 구현) 문제를 해결하지 못합니다 .
Nik Bougalis 2015

Erik의 대답을 참조하십시오. 더 나은 해결책이라고 생각합니다. 덜 해키하고 명확합니다.
PolyMesh 2016-07-28

28

다른 사람들이 언급했듯이 오류는 Windows 헤더에 정의 된 최소 / 최대 매크로로 인해 발생합니다. 비활성화하는 방법에는 세 가지가 있습니다.

1) #define NOMINMAX헤더를 포함하기 전에 이것은 일반적으로 다음 헤더에 영향을 미치기 위해 매크로를 정의하는 잘못된 기술입니다.

2) NOMINMAX컴파일러 명령 줄 / IDE에서 정의 합니다. 이 결정의 나쁜 점은 소스를 제공하려는 경우 사용자에게 동일한 작업을 수행하도록 경고해야한다는 것입니다.

3) 매크로를 사용하기 전에 코드에서 매크로를 정의 해제하십시오.

#undef min
#undef max

이것은 아마도 가장 휴대 가능하고 유연한 솔루션 일 것입니다.


2
옵션 1의 또 다른 문제는 단순히 항상 작동하지 않는다는 것입니다. gdiplus.h와 같이 실제로 필요한 다른 창 헤더가 포함될 수 있습니다. 이 경우 옵션 3이 유일한 희망일 수 있습니다.
shawn1874 2014

27

나는 여전히 Windows 헤더에 문제가 있으며 NOMINMAX의 프로젝트 전체 정의가 항상 작동하지 않는 것 같습니다. 괄호를 사용하는 대신 다음과 같이 유형을 명시 적으로 만드는 경우가 있습니다.

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

이것은 또한 전처리 기가 일치하는 것을 중지 min하고 괄호 해결 방법보다 더 읽기 쉽습니다.


3
동의합니다. 이것이 최선의 해결책입니다. 나는 다른 사람이 나를 때리는 것을 보았을 때 다른 대답을하기 위해 돌아왔다.
PolyMesh

16

다음과 같이 시도하십시오.

#define NOMINMAX
#include <windows.h>

기본적으로 windows.h는 minmax매크로를 정의 합니다. 그것들이 확장되면 std::min(예를 들어) 사용하려는 코드는 다음과 같이 보일 것입니다.

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

오류 메시지는 std::(x)허용되지 않음을 알려줍니다 .


5

내 경우, 프로젝트는 포함하지 않았다 windows.h또는 windef.h명시 적으로. Boost를 사용하고있었습니다. 그래서 프로젝트로 이동 하여 (VS 2013, VS 2015)에 Properties -> C/C++ -> Preprocessor추가 하여 문제를 해결했습니다 .NOMINMAXPreprocessor Definitions


VS 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 min 및 max.

#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가 min을 매크로로 정의한다고 가정합니다.

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

그것은 오류 메시지를 설명합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.