컴퓨터/Window$

IDE 버전별 C++ 표준 지원 일람

Subi Lee 2016. 12. 31.
반응형

MSDN 페이지: https://msdn.microsoft.com/ko-kr/library/hh567368.aspx?f=255&MSPPError=-2147217396


C++11/14/17 기능에 대한 지원(최신 C++)

Visual Studio 2015
 

Visual Studio 2017 RC에 대한 최신 설명서는 Visual Studio 2017 RC 설명서를 참조하세요.

이 문서에서는 Visual C++의 C++11/14/17 기능에 대해 설명합니다.

Visual C++는 C++11 핵심 언어 사양에 포함된 대부분의 기능과 많은 C++14 라이브러리 기능 및 C++17에 대해 제안된 일부 기능을 구현합니다. 다음 표에서는 Visual Studio 2010, Visual Studio 2012의 Visual C++, Visual Studio 2013의 Visual C++ 및 Visual Studio 2015의 Visual C++에서 C++11/14/17 핵심 언어 기능 및 해당 구현 상태를 보여 줍니다.

C++11 핵심 언어 기능 표

C++11 핵심 언어 기능Visual Studio 2010Visual Studio 2012Visual Studio 2013Visual Studio 2015
Rvalue 참조 v0.1v1.0v2.0v2.1v3.0v2.0v2.1*v2.1*v3.0
ref-qualifiers아니요아니요아니요
비정적 데이터 멤버 이니셜라이저아니요아니요
Variadic 템플릿 v0.9v1.0아니요아니요
이니셜라이저 목록아니요아니요
static_assert
auto v0.9v1.0v1.0v1.0v1.0
후행 반환 형식
람다 v0.9v1.0v1.1v1.0v1.1v1.1
decltype v1.0v1.1v1.0v1.1**v1.1
오른쪽 꺾쇠 괄호
함수 템플릿의 기본 템플릿 인수아니요아니요
Expression SFINAE아니요아니요아니요아니요
별칭 템플릿아니요아니요
Extern 템플릿
nullptr
강력한 형식의 열거형Partial
전방 선언 열거형아니요
특성아니요아니요아니요
constexpr아니요아니요아니요
맞춤TR1PartialPartial
위임 생성자아니요아니요
상속 생성자아니요아니요아니요
명시적 변환 연산자아니요아니요
char16_t/char32_t아니요아니요아니요
유니코드 문자열 리터럴아니요아니요아니요
원시 문자열 리터럴아니요아니요
리터럴의 유니버설 문자 이름아니요아니요아니요
사용자 정의 리터럴아니요아니요아니요
표준 레이아웃 및 Trivial 형식아니요
기본 설정 및 삭제된 함수아니요아니요예*
확장된 friend 선언
확장된 sizeof아니요아니요아니요
인라인 네임스페이스아니요아니요아니요
무제한 공용 구조체아니요아니요아니요
로컬 및 명명되지 않은 형식을 템플릿 인수로 사용
Range-based for 루프아니요
override 및 final v0.8v0.9v1.0Partial
최소한의 GC 지원
noexcept아니요아니요아니요

[이 문서의 내용]

C++11 핵심 언어 기능 표: 동시성

C++11 핵심 언어 기능: 동시성Visual Studio 2010Visual Studio 2012Visual Studio 2013Visual Studio 2015
다시 표시된 시퀀스 위치N/AN/AN/A
원자성아니요
강력한 비교 및 교환아니요
양방향 펜스아니요
메모리 모델N/AN/AN/A
데이터 종속성 순서 지정아니요
데이터 종속성 순서 지정: 함수 주석아니요아니요아니요
exception_ptr
quick_exit아니요아니요아니요
신호 처리기의 원자성아니요아니요아니요아니요
스레드 로컬 저장소PartialPartialPartial
매직 정적 이름아니요아니요아니요

[이 문서의 내용]

C++11 핵심 언어 기능: C99

C++11 핵심 언어 기능: C99Visual Studio 2010Visual Studio 2012Visual Studio 2013Visual Studio 2015
__func__PartialPartialPartial
C99 전처리기PartialPartialPartialPartial
long long
확장된 정수 형식N/AN/AN/AN/A

[이 문서의 내용]

C++14 핵심 언어 기능

기능Visual Studio 2013Visual Studio 2015
컨텍스트 변환에 대해 조정된 작업
이진 리터럴아니요
auto 및 decltype(auto) 반환 형식아니요
init 캡처아니요
제네릭 람다아니요
변수 템플릿아니요아니요
확장된 constexpr아니요아니요
집합체에 대한 NSDMI아니요아니요
할당 방지/융합아니요아니요
[[deprecated]] 특성아니요아니요
크기가 지정된 할당아니요
자릿수 구분 기호아니요

C++17 제안된 핵심 언어 기능

기능Visual Studio 2013Visual Studio 2015
중괄호로 묶인 Init 목록을 사용한 auto에 대한 새 규칙아니요아니요
간결한 정적 어설션아니요아니요
템플릿 template-parameters의 typename아니요아니요
삼중자 제거
중첩된 네임스페이스 정의아니요아니요
N4259 std::uncaught_exceptions()아니요아니요
N4261 한정 변환 수정아니요아니요
N4266 네임스페이스 및 열거자에 대한 특성아니요아니요
N4267 u8 문자 리터럴아니요아니요
N4268 더 많은 비형식 템플릿 인수 허용아니요아니요
N4295 식 폴딩아니요아니요
await/resume아니요

Rvalue 참조

System_CAPS_ICON_note.jpg 참고

다음 설명의 버전 지정(v0.1, v1.0, v2.0, v2.1, v3.0)은 단순히 C++11의 발전을 보여주기 위해 만든 것입니다. 표준 자체에서는 사용하지 않습니다.

N1610 "rvalue로 클래스 개체 초기화 확인"은 rvalue 참조 없이 초기에 이동 의미 체계를 사용하려 했습니다. 설명을 위해 "rvalue 참조 v0.1"이라고 하겠습니다. "rvalue 참조v1.0"으로 대체되었습니다. Visual Studio 2010의 Visual C++ 작업이 기반으로 하는 "Rvalue 참조 v2.0"에서는 rvalue 참조가 lvalue에 바인딩하지 못하도록 하여 주요 안전 문제를 해결합니다. "Rvalue 참조 v2.1"에서 이 규칙을 구체적으로 지정합니다. 오버로드 push_back(const string&) 및 push_back(string&&)를 갖는 vector<string>::push_back()를 고려하고 v.push_back("strval")을 호출합니다."strval" 식은 문자열 리터럴이며 lvalue입니다. (다른 리터럴, 예를 들어 정수 1729는 rvalue이지만, 문자열 리터럴은 배열이므로 특수합니다.) "rvalue 참조 v2.0" 규칙에는 string&&이 lvalue이기 때문에 "strval"를 "strval"에 바인딩할 수 없다고 되어 있으므로 push_back(const string&)이 유일한 후보 오버로드입니다. 그러면 효율적이지 않은 방식으로 임시 std::string을 만들고, 이를 벡터에 복사한 후 임시 std::string을 삭제합니다. "rvalue 참조 v2.1" 규칙은 string&&의 "strval"에 대한 바인딩이 임시 std::string를 만들고 이 임시 값이 rvalue임을 인식합니다. 따라서 push_back(const string&) 및 push_back(string&&) 둘 다 후보이며 push_back(string&&)이 선호됩니다. 임시 std::string이 생성된 다음 벡터로 이동합니다. 이 방식이 더 효율적입니다.

"Rvalue 참조 v3.0"은 특정 조건에서 이동 생성자를 자동으로 생성하고 할당 연산자를 이동하는 새 규칙을 추가합니다. Visual Studio 2015에서 구현되었습니다.

[이 문서의 내용]

람다

람다 함수가 작업 용지(버전 "0.9")로 가결되고 변형 가능한 람다가 추가(버전 "1.0")된 후 표준화 위원회에서 단어를 점검했습니다. 이를 통해 버전 "1.1" 람다가 생성되었지만 이 람다는 현재 완벽하게 지원되지 않습니다. V1.1 람다 표현은 정적 멤버 또는 중첩된 람다 식과 같은 코너 케이스에서 발생하는 것을 명확히 보여 줍니다. 이 표현은 복잡한 람다에서 발생하는 문제를 해결합니다. 또한 이제 상태 비저장 람다를 함수 포인터로 변환할 수 있습니다. N2927 표현에는 없지만 람다 v1.1에 포함된 것으로 간주됩니다.C++115.1.2 [expr.prim.lambda]/6에는 다음과 같은 설명이 포함되어 있습니다. "lambda-capture가 없는 lambda-expression의 클로저 형식에는 클로저 형식의 함수 호출 연산자와 동일한 매개 변수 및 반환 형식을 가진 함수 포인터에 대한 공용 비가상 비명시적 상수 변환 함수가 있습니다. 이 변환 함수로 반환되는 값은 호출된 경우 클로저 형식의 함수 호출 연산자를 호출하는 것과 동일한 효과를 갖는 함수 주소여야 합니다." (임의의 호출 규칙을 가진 함수 포인터로 변환 가능한 상태 비저장 람다를 만들므로 Visual Studio 2012의 Visual C++ 구현이 훨씬 효율적입니다.) 이는 __stdcall과 같은 함수 포인터가 필요한 API를 사용할 경우 중요합니다.

[이 문서의 내용]

decltype

작업 용지(버전 1.0)에 decltype이 가결된 후, 릴리스 바로 전에 작지만 중요한 해결책을 받았습니다(버전 1.1). STL 및 Boost로 작업하는 프로그래머에게 흥미로운 내용입니다.

[이 문서의 내용]

강력한 형식/전방 선언 열거형

강력한 형식의 열거형은 Visual Studio 2010의 Visual C++에서 부분적으로 지원되었습니다(특히 명시적으로 지정되는 기본 형식). 이제 Visual Studio에서 완전히 구현되며 전방 선언 열거형에 대한 C++11 의미 체계도 완전히 구현됩니다.

[이 문서의 내용]

맞춤

작업 용지에 기표되는 조정 제안서의 핵심 언어 키워드 alignas/alignof가 Visual Studio 2015에서 구현되었습니다. Visual Studio 2010의 Visual C++에는 TR1의 aligned_storage가 포함되었습니다.Visual Studio 2012의 Visual C++은 aligned_union 및 std::align()을 표준 라이브러리에 추가하였고, Visual Studio 2013의 Visual C++에서 중요한 문제가 수정되었습니다.

[이 문서의 내용]

표준 레이아웃 및 Trivial 형식

N2342 "POD's Revisited; Resolving Core Issue 568 (Revision 5)"의 노출된 변경은 is_trivial 및 is_standard_layout을 표준 템플릿 라이브러리의 <type_traits>에 추가합니다. (N2342에서 핵심 언어의 많은 단어를 재작업했지만 컴파일러 변경은 필요하지 않습니다.) 이러한 형식 특성은 Visual Studio 2010의 Visual C++에서 사용할 수 있었지만 is_pod은 중복되었습니다. 그러므로 이 문서 앞 부분의 표에는 지원되지 않는 것으로 나와 있습니다. 이제는 정확한 답을 제공하도록 설계된 컴파일러 후크를 사용할 수 있습니다.

STL의 common_type<>은 Visual Studio 2013의 Visual C++에서 매우 필요한 수정 프로그램을 받았습니다.common_type<>에 대한 C++11 사양에 예기치 않은 결과가 발생했습니다. 특히 common_type<int, int>::type은 int&&를 반환합니다. 따라서 Visual Studio 2013의 Visual C++은 Proposed Resolution for Library Working Group issue 2141을 구현하며 이를 통해 common_type<int, int>::type은 int를 반환합니다.

이 변경의 부작용으로 ID의 경우가 더 이상 작동하지 않습니다(common_type<T>가 T 형식을 생성하지 않는 경우도 있음). 이는 제안된 해결 방법을 사용하여 컴파일되지만 이전 동작에 의존하는 모든 코드가 중단됩니다.

ID 형식 특성이 필요한 경우 std::identity에 정의된 비표준 <type_traits>는 <void>에 대해 작동하지 않으므로 사용하지 마세요. 대신 필요에 따라 고유한 ID 형식 특성을 구현합니다. 예를 들면 다음과 같습니다.

template <typename T> struct Identity { typedef T type; };  
  

System_CAPS_ICON_note.jpg 참고

기타 주요 변경 내용은 Visual C++ 2015의 주요 변경 내용을 참조하세요.

[이 문서의 내용]

기본 설정 및 삭제된 함수

이제 지원되지만 다음 예외가 발생합니다. 기본 함수의 경우 멤버 이동 생성자 및 이동 할당 연산자를 요청하기 위한 =default사용은 지원되지 않습니다. 복사 및 이동이 표준에서 지정한 대로 정확하게 상호 작용하지 않습니다. 예를 들어 이동 삭제는 복사도 비활성화하도록 지정되지만 Visual Studio 2013의 Visual C++는 그렇지 않습니다.

기본 설정 및 삭제된 함수를 사용하는 방법에 대한 자세한 내용은 함수를 참조하세요.

[이 문서의 내용]

override 및 final

이 과정은 짧지만 복잡한 진화였습니다. 원래 버전 0.8에는 [[override]], [[hiding]] 및 [[base_check]] 특성이 있었습니다.버전 0.9에서는 이 특성이 제거되어 컨텍스트 키워드로 대체되었습니다. 마지막으로 버전 1.0에서는 클래스의 "final", 함수의 "override" 및 "final"로 축소되었습니다. Visual Studio 2010의 Visual C++에서는 이미 이 "override" 구문이 함수에서 지원되고 C++11과 상당히 비슷한 의미 체계를 갖기 때문에 이를 Ascended 확장으로 설정합니다. "final"도 지원되지만 스펠링이 다른 "sealed"에서 사용한 경우입니다. "override" 및 "final"의 표준 철자와 의미 체계가 이제 완전하게 지원됩니다. 자세한 내용은 override 지정자 및 final 지정자를 참조하세요.

[이 문서의 내용]

원자성 등

원자성강력한 비교 및 교환양방향 펜스 및 데이터 종속 순서지정에서는 구현이 완료된 표준 라이브러리 시스템을 지정합니다.

관련 STL 헤더: <atomic><chrono><condition_variable><future><mutex><ratio><scoped_allocator>, and <thread>.

[이 문서의 내용]

C99 __func__ 및 전처리기 규칙

C++11 핵심 언어 기능: C99표에는 항목에 대한 "부분" 구현이 나열됩니다. 사전 정의된 식별자인 __func__의 경우 비표준 확장 __FUNCDNAME____FUNCSIG__ 및 __FUNCTION__만 지원되므로 "부분"이 표시됩니다. 자세한 내용은 미리 정의된 매크로을 참조하세요. C99 전처리기 규칙의 경우 variadic 매크로가 지원되므로 "부분"이 표시됩니다. 자세한 내용은 Variadic 매크로을 참조하세요.

[이 문서의 내용]

표준 라이브러리 기능

핵심 언어를 다룹니다. C++11 표준 라이브러리의 경우 마땅한 기능 비교 표는 없지만 Visual Studio 2012의 Visual C++에서 이를 구현했습니다(단, 두 가지 예외가 있음). 먼저 라이브러리 기능이 컴파일러에 없는 기능에 종속되면 시뮬레이션되었거나(예: make_shared<T>()의 경우 시뮬레이션된 variadic 템플릿) 구현되지 않은 것입니다. (특히 <initializer_list>를 포함하여 Visual Studio 2013의 Visual C++에서 완전히 구현된 몇 가지 사례만 있습니다.) 거의 예외 없이 C99는 Visual Studio 2013의 Visual C++ 및 제공된 C++ 래퍼 헤더에 구현되었습니다. 자세한 내용은 Visual Studio 2013의 C99 라이브러리 지원(영문)을 참조하세요.

다음은 Visual Studio 2012의 Visual C++ 및 Visual Studio 2013의 Visual C++의 일부 변경 사항 목록입니다.

Emplacement: C++11에 필요하기 때문에 "임의" 개수의 인수에 대해 모든 컨테이너에서 emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after()가 구현되었습니다("시뮬레이션된 variadics" 단원 참조). 예를 들어, vector<T>에는 완벽하게 전달된 임의 개수의 임의 인수에서 벡터 뒤에 T 형식의 요소를 직접 생성하는 "template <typename... Args> void emplace_back(Args&&... args)"이 있습니다. 이는 추가 이동 생성 및 소멸을 포함하는 push_back(T&&)보다 더 효과적일 수 있습니다.

Variadics: Visual Studio 2012의 Visual C++에는 variadic 템플릿을 시뮬레이트하기 위한 스키마가 포함되었습니다.Visual Studio 2013의 Visual C++에서 시뮬레이션이 사라지고 variadics가 완전히 구현됩니다. 코드가 예전에 시뮬레이션된 variadics 동작에 의존하는 경우 수정해야 합니다. 그러나 실제 variadic 템플릿으로 전환하면 컴파일 시간 향상 및 컴파일러 메모리 소비 감소가 발생합니다.

명시적 변환 연산자: 핵심 언어에서 명시적 변환 연산자는 일반적인 기능입니다. 예를 들어 explicit operator MyClass()를 가질 수 있습니다. 그러나 표준 라이브러리는 현재 explicit operator bool() 폼 하나만 사용합니다. 클래스를 안전하게 부울 테스트할 수 있기 때문입니다. (일반 "operator bool()"은 매우 위험합니다.) 이전에는 Visual C++이 operator pointer-to-member()를 사용하여 explicit operator bool()를 시뮬레이트했으므로 다양한 문제가 발생했고 효율성이 부족한 면이 있었습니다. 이제, "가짜 bool" 해결 방법은 완전히 제거됩니다.

임의성: uniform_int_distribution는 이제 완벽하게 공평성을 지니고 shuffle()이 <algorithm>에 구현되어 mersenne_twister 같은 Uniform Random Number Generators를 직접 수락합니다.

오버로드된 address-of 연산자 금지: C++98/03에서는 STL 컨테이너 요소가 해당 address-of 연산자를 오버로드하는 것이 금지되었습니다.CComPtr와 같은 도우미 클래스가 이러한 오버로드로부터 STL을 보호하도록 설정하기 위해 CAdapt과 같은 클래스가 수행하는 작업입니다. Visual Studio 2010에서 Visual C++ 개발 중 더 많은 상황에서 오버로드된 address-of 연산자를 거부하도록 STL이 변경되었습니다. C++11은 오버로드된 address-of 연산자를 허용하도록 하는 요구 사항을 변경했습니다. C++11 및 Visual Studio 2010의 Visual C++는 연산자 오버로드와 관계없이 개체의 실제 주소를 가져올 수 있는 도우미 함수 std::addressof()를 제공합니다. Visual C++ in Visual Studio 2010을 릴리스하기 전에 "&elem"의 발생을 적절한 내구성이 있는 "std::addressof(elem)"로 바꾸려고 했습니다.Visual Studio 2012의 Visual C++가 발전되었으므로 연산자의 주소를 오버로드하는 클래스는 STL을 통해 사용할 수 있어야 합니다.

Visual Studio 2012의 Visual C++는 여러 방식으로 C++11보다 더 뛰어난 기능을 제공합니다.

SCARY 반복기: N2911 "빠르고 작은 프로그램을 위해 제네릭 클래스 내의 종속성 최소화" 및 N2980 "SCARY 반복기 할당 및 초기화, 개정 1"에 설명된 대로 C++11 표준에서 허용되기는 하지만 필수가 아닌 SCARY 반복기가 구현되었습니다.

파일 시스템: TR2 제안의 <filesystem> 헤더가 추가되었습니다.recursive_directory_iterator 및 기타 흥미로운 기능을 제공합니다. TR2 작업이 중지되기 전에 C++0x 실행 속도가 매우 느렸고 C++11로 변경되고 있었기 때문에 Boost.Filesystem V2에서 2006 제안이 파생되었습니다. 나중에 Visual Studio 2015에서 구현된 Boost.Filesystem V3로 발전했습니다.

또한 최적화가 크게 개선되었습니다! 모든 컨테이너는 이제 현재 자신의 표현에 따라 최적으로 작습니다. 이는 컨테이너 개체 자신을 가리키며, 가리키는 대상의 콘텐츠를 가리키지 않습니다. 예를 들어, std::vector에는 세 가지 원시 포인터가 포함됩니다. Visual Studio 2010의 Visual C++, x86 릴리스 모드에서 std::vector는 16바이트입니다.Visual Studio 2012의 Visual C++에서는 최적으로 작은 12바이트입니다. 프로그램에 100,000개의 벡터가 있으면 Visual Studio 2012의 Visual C++를 통해 400,000바이트를 절약할 수 있습니다. 메모리 사용을 줄이면 공간과 시간이 둘 다 절감됩니다.

이 결과는 std::allocator 및 std::less는 상태 비저장이므로 비어 있는 할당자 및 비교자를 저장하지 않은 결과입니다. (이러한 최적화는 상태를 저장하지 않는 이상 사용자 지정 할당자/비교 연산자에 사용할 수 있습니다. 물론, 상태 저장 할당자/비교 연산자의 저장을 방지할 수 없지만 매우 드문 경우입니다.)

Visual Studio 2013의 Visual C++에서는 몇 개의 C++14 라이브러리 기능을 구현했습니다.

  • less<>greater<>plus<>multiplies<> 등의 "투명 연산자 함수"

  • make_unique<T>(args...) 및 make_unique<T[]>(n)

  • cbegin()/cend()rbegin()/rend() 및 crbegin()/crend() 비멤버 함수

[이 문서의 내용]

C++의 진화
C++ 언어 참조
람다 식
범위 기반 for 문(C++)
C++ 표준 라이브러리
Visual C++ 팀 블로그
Visual C++의 새로운 기능
Visual C++ 2015의 주요 변경 내용


반응형

댓글