C ++ 11 지원을 어떻게 확인합니까?


104

컴파일러가 C ++ 11의 특정 기능을 지원하는 경우 컴파일 타임에 감지하는 방법이 있습니까? 예를 들면 다음과 같습니다.

#ifndef VARIADIC_TEMPLATES_SUPPORTED

#error "Your compiler doesn't support variadic templates.  :("

#else

template <typename... DatatypeList>
class Tuple
{
    // ...
}

#endif

2
포함 할 수있는 "assert_variadic_template_support.hpp"라는 헤더를 가질 수 있으며 template <typename... Test> struct compiler_must_support_variadic_templates;. 구문 오류는 문제를 빠르게 드러냅니다. (제외로 적절한 오류 메시지가 훨씬 낫습니다.)
GManNickG

이 문제를 해결하는 '올바른'방법은 구성 테스트입니다.
조셉 가빈

답변:


125

__cplusplusC ++ 컴파일러가 지원되는 C ++ 표준 버전으로 설정해야하는 상수가 있습니다. 이를 참조

#if __cplusplus <= 199711L
  #error This library needs at least a C++11 compliant compiler
#endif

Visual Studio 2010 SP1에서는 199711L로 설정되어 있지만 모든 C ++ 11 변경 사항이있는 표준 C ++ 라이브러리에 비해 (일부) 컴파일러 수준 지원 만있는 경우 공급 업체가 이미이를 늘릴만큼 과감한 것인지는 모르겠습니다. .

따라서 다른 답변에서 언급 된 Boost의 정의는 예를 들어 C ++ 11 스레드 및 표준의 다른 특정 부분에 대한 지원이 있는지 알아내는 유일한 방법입니다.


37
C ++ 11은의 값 __cplusplus201103L. 이는 2011 표준에 대한 완전한 준수를 주장합니다. 부분적 적합성이나 컴파일러 확장에 대해서는 알려주지 않습니다. 경우는 __cplusplus로 설정 201103L하거나 다음 컴파일러 완전히 부합 함을 선언을하거나 당신에게 거짓말. 그렇지 않다면 어떤 기능을 지원하는지 알 수 없습니다.
Keith Thompson

1
g ++ 4.7.x (그리고 아마도 최신 버전)는 -std=c++11옵션이 지정 될 때이를 설정 합니다 (와 함께도 가능 -std=gnu++11). 기능이 완벽하지는 않지만 (4.8이 훨씬 더 가까워짐)이를 수행합니다. 참고-컴파일러가 지원하는 것과 표준 라이브러리에서 사용할 수있는 것 사이에 차이가 있습니다. 4.7.x 및 4.8.x 모두 현재 정규식 지원이 누락되었지만 컴파일러 기능이 아닌 라이브러리입니다.
Nathan Ernst

1
왜 이것이 받아 들여지지 않는 대답인지 궁금합니다. 또한 이 제안 을 사용 하여 답변을 더욱 개선 할 수 있습니다 . 매우 좋습니다.
Iharob Al Asimi 2015

1
@KeithThompson 나를 위해 Code :: Blocks와 Visual Studio 모두 C ++ 11 의 값을 __cplusplus로 설정했습니다 199711L.
Donald Duck

3
@DonaldDuck : 엄밀히 말하면, 아닙니다. 컴파일러 그 세트 __cplusplus199711L순응 C ++ 컴파일러 11이 아니다. 그들은 아마도 그들이 올바르게 작동하도록하는 옵션을 가지고있을 것입니다.
Keith Thompson

39

C ++ 11 표준 (§iso.16.8)에 명시된대로 :

__cplusplus 라는 이름 은 C ++ 번역 단위를 컴파일 할 때 값 201103L로 정의됩니다 .

해당 매크로의 값을 사용하여 컴파일러가 C ++ 11과 호환되는지 여부를 확인할 수 있습니다.

이제 컴파일러가 C ++ 11 기능의 하위 집합을 지원하는지 확인하는 표준 방법을 찾고 있다면 표준 이식 방법이 없다고 생각합니다. 자세한 정보를 얻으려면 컴파일러 문서 또는 표준 라이브러리 헤더 파일을 확인할 수 있습니다.


2
예를 들어 static_assert는 VS2010 및 모든 C ++ 11 copiler에서 지원됩니다. 따라서 VS2010에 설정된 값보다 크거나 같은 __cplusplus 값을 확인하면 (즉> = 199711L) 괜찮을 수 있습니다.
Paolo M

33

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만이 질문은 자주 볼 수 있으며 답변은 약간 구식입니다.

C ++ 14 표준을 사용하는 최신 컴파일러에는 C ++ 11 기능을 포함하여 기능을 확인하는 표준 방법이 있습니다. 포괄적 인 페이지는 https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations에 있습니다.

요약하면 각 기능에는에서 확인할 수있는 정의 된 표준 매크로가 있습니다 #ifdef. 예를 들어 사용자 정의 리터럴을 확인하려면 다음을 사용할 수 있습니다.

#ifdef __cpp_user_defined_literals

1
나는 그것을 몰랐다. 이 간단한 기능이 늦게 나올 것이라고 생각하지만, 특히 __has_include()매크로 에서 여전히 매우 유용 할 수 있습니다 .
prapin

22

확인 지원 C ++ 14 및 기타. GCC 5.2.1에서 테스트.

#include <iostream>

int main(){
        #if __cplusplus==201402L
        std::cout << "C++14" << std::endl;
        #elif __cplusplus==201103L
        std::cout << "C++11" << std::endl;
        #else
        std::cout << "C++" << std::endl;
        #endif

        return 0;
}

17

이것을 사용할 수 있습니다 :

#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
    cout << "C++11 is supported";
#else
    cout << "C++11 is not supported";
#endif

C ++ 11의 경우 Visual Studio를 제외한 대부분의 컴파일러는 __cplusplus매크로를에 설정 201103L하지만 모든 버전의 Visual Studio는 199711LC ++ 11 이전의 다른 컴파일러에 사용 된 값으로 매크로를 설정합니다 . 이 코드는 Visual Studio를 제외한 모든 컴파일러 의 _cplusplus매크로와 비교하고 201103L컴파일러가 Visual Studio 인 경우 Visual Studio의 버전이 C ++ 11을 완전히 지원하는 Visual Studio의 첫 번째 버전 인 2015 이후인지 확인합니다 (Visual Studio 2015, _MSC_VER매크로에는 값 있습니다. 이 답변1900 참조 ).


1
이 대답은 틀 렸습니다. 들어 g++ -std=c++98GCC 4.8, 그것은 잘못 인쇄 C++11 is supported.
pts

1
@pts 죄송합니다. 오타입니다. 지금 수정해야합니다.
Donald Duck

7

Boost.Config를 사용하지 않고 C ++ 11을 지원하는 컴파일러를 테스트해야하는 경우 상수 값을 확인하면 __cplusplus됩니다. 그러나 컴파일러는 C ++ 11 표준의 인기있는 기능 대부분을 지원할 수 있지만 전체 사양을 지원하지는 않습니다. 아직 C ++ 11 사양을 100 % 준수하지 않는 특정 Visual Studio 컴파일러에 대한 지원을 활성화하려면 Visual Studio 2013에서 컴파일 할 수있는 다음 코드 조각을 사용합니다.

#if defined(_MSC_VER)
#   if _MSC_VER < 1800 
#       error This project needs atleast Visual Studio 2013
#   endif
#elif __cplusplus <= 199711L
#   error This project can only be compiled with a compiler that supports C++11
#endif

Visual Studio 용 컴파일러 버전의 전체 목록은 Visual Studio 2008을 사용하여 코드를 컴파일하고 있는지 감지하는 방법에서 제공됩니다.


6

전통적인 Linux / Unix 세계에서 autoconf는 전통적으로 라이브러리 및 컴파일러 기능의 존재 여부를 테스트하고 필요에 따라 파일에서 사용하는 config.h에 버그를 배치하는 데 사용됩니다.


2
예 autoconf를 사용하여 기능을 테스트 할 수 있지만 실패 또는 성공에 대한 적절한 매크로를 생성해야 위의 코드로 테스트 할 수 있습니다. 따라서이 답변 자체는 정보를 추가하지 않습니다.
Martin York

3
@LokiAstari : 그것은 autoconf가 작동하는 방식이 아닙니다. Autoconf는 구성 스크립트가 테스트 소스 파일을 컴파일하고 컴파일 성공 여부에 따라 #define을 0 또는 1로 설정할 수있는 매크로를 제공합니다. diverscuba23의 답변은 OP가 실제 문제에 대한 차선책에 도달하고 있음을 지적함으로써 정보를 제공합니다.
조셉 가빈


1

C ++ 11 라이브러리 가용성 (언어 기능 아님)을 확인하는 경우 예를 들어 <array> 헤더)을 확인하는 경우 다음을 수행 할 수 있습니다.#if __has_include(<array>) .

때때로 검사 #if __cplusplus >= 201103L는 C ++ 11을 사용한다고 알려 주지만 Xcode의 표준 라이브러리 버전 설정과 같은 다른 설정은 여전히 ​​새 라이브러리를 사용할 수 없을 수 있습니다 (대부분은 다른 이름으로 사용할 수 있음 <tr1/array>).

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