C++11
C++11이 기사는 대부분의 독자가 이해하기에는 너무 기술적일 수 있습니다.. (2017년 3월) (본 의 및 에 대해 을 삭제하지 할 수 하는 데 을 바랍니다 |
C++ 언어 수정본 |
---|
C++11은 C++ 프로그래밍 언어를 위한 ISO/IEC 14882 표준의 버전입니다. C++11은 C++03이라고 불리는 이전 버전의 C++ 표준을 대체했고,[1] 나중에 C++14로 대체되었습니다. 이 이름은 2010년 이전에 발표될 것으로 예상되었기 때문에 이전에는 C++0x로 명명되었지만, 표준의 출판 연도에 따라 언어 버전을 명명하는 전통을 따릅니다.[2]
설계 목표 중 하나는 코어 언어에 대한 변경보다 라이브러리에 대한 변경을 선호하는 [3]것이었지만 C++11은 코어 언어에 몇 가지 추가를 수행합니다. 핵심 언어 중에서 크게 향상된 분야는 멀티스레딩 지원, 일반 프로그래밍 지원, 균일한 초기화, 성능 등입니다. 수학적 특수 함수의 라이브러리를 제외한 대부분의 C++ 기술 보고서 1(TR1) 라이브러리를 통합하는 C++ 표준 라이브러리에도 상당한 변화가 있었습니다.[4]
C++11은 2011년 9월 ISO/IEC 14882:2011으로[5] 발행되었으며 유료로 제공됩니다. 공개된 C++11 표준과 가장 유사한 작업 초안은 2012년 1월 16일자 N3337이며,[6] C++11 표준의 편집 수정만 있습니다.[7]
C++11은 Clang 3.3 이상에서 완벽하게 지원됩니다.[8] C++11은 GCC 4.8.1 이상에서 완벽하게 지원됩니다.[9]
설계목표
설계 위원회는 C++11을 설계하는 데 있어 여러 가지 목표를 고수하려고 했습니다.
- C++98 및 C와의 안정성 및 호환성 유지
- 핵심 언어를 확장하는 것보다 표준 라이브러리를 통해 새로운 기능을 도입하는 것을 선호합니다.
- 프로그래밍 기술을 발전시킬 수 있는 변경사항 선호
- C++를 개선하여 특정 애플리케이션에만 유용한 새로운 기능을 도입하는 대신 시스템 및 라이브러리 설계를 용이하게 합니다.
- 이전의 안전하지 않은 기술에 대한 안전한 대안을 제공하여 형식 안전성 향상
- 하드웨어로 직접 작업할 수 있는 성능 및 기능 향상
- 실제 문제에 대한 적절한 솔루션 제공
- 제로 오버헤드 원칙 구현(일부 유틸리티에서 필요한 추가 지원은 유틸리티를 사용하는 경우에만 사용해야 함)
- 전문 프로그래머가 필요로 하는 유틸리티를 제거하지 않고도 C++를 쉽게 가르치고 학습할 수 있습니다.
대부분의 컴퓨터 프로그래머들은 항상 그렇게 될 것이기 때문에, 그리고 많은 초보자들은 그들의 지식을 결코 넓히지 않고, 그들이 전문적으로 다루는 언어의 측면에서 일하도록 그들 자신을 제한하기 때문에, 초보자들에게 주의를 기울이는 것은 중요하게 여겨집니다.[1][failed verification]
C++ 핵심 언어에 대한 확장
C++ 위원회의 한 가지 기능은 언어 핵심의 발전입니다. 핵심 언어 중에서 크게 향상된 분야는 멀티스레딩 지원, 일반 프로그래밍 지원, 균일한 초기화, 성능 등입니다.
핵심 언어 런타임 성능 향상
이러한 언어 기능은 주로 메모리 또는 계산 속도와 같은 일종의 성능 이점을 제공하기 위해 존재합니다.[citation needed]
R값 참조 및 생성자 이동
C++03(및 이전)에서 임시("rvalues"라고 함)는 C에서와 마찬가지로 절대 수정할 수 없으며, 구별할 수 없는 것으로 간주되었습니다. const T&
유형; 그럼에도 불구하고 어떤 경우에는 임시가 수정될 수도 있습니다. 이 동작은 유용한 허점으로 여겨지기도 했습니다.[10] C++11은 non-constant reference type을 새로 추가합니다. rvalue 참조, 에 의해 식별됨 T&&
. 이것은 "의미 이동"을 허용하기 위한 목적으로 초기화된 후 수정이 허용되는 임시를 말합니다.
C++03의 만성적인 성능 문제는 값 단위로 개체를 전달할 때 암묵적으로 발생할 수 있는 값비싼 불필요한 심층 복사본입니다. 문제를 설명하려면 다음을 고려하십시오. std::vector<T>
는 내부적으로 정의된 크기의 C-스타일 어레이 주변의 래퍼입니다. 만약 std::vector<T>
임시는 함수에서 생성되거나 반환되며 새 함수를 생성해야만 저장할 수 있습니다. std::vector<T>
모든 r값의 데이터를 복사합니다. 그러면 임시 메모리와 모든 메모리가 파괴됩니다. (간단성을 위해 이 논의에서는 반환 값 최적화를 무시합니다.)
C++11에서 이동 생성자는 std::vector<T>
에 대한 r값 참조를 사용하는 std::vector<T>
R 값에서 내부 C-스타일 배열로 포인터를 새 값으로 복사할 수 있습니다. std::vector<T>
, 그런 다음 r값 내부의 포인터를 null로 설정합니다. 임시는 다시는 사용되지 않으므로 null 포인터에 액세스하려는 코드는 없으며 포인터가 null이기 때문에 범위를 벗어나도 메모리가 삭제되지 않습니다. 따라서 작업은 심층 복사본의 비용을 포기할 뿐만 아니라 안전하고 보이지 않습니다.
Rvalue 참조는 표준 라이브러리 외부에서 변경할 필요 없이 기존 코드에 성능 이점을 제공할 수 있습니다. 반환되는 함수의 반환 값의 유형 std::vector<T>
임시는 명시적으로 변경할 필요가 없습니다. std::vector<T> &&
임시는 자동으로 r값으로 간주되므로 move computer를 호출합니다. (단, 만약 std::vector<T>
이동 생성기가 없는 C++03 버전입니다. 그러면 복사 생성기가 다음과 함께 호출됩니다. const std::vector<T>&
, 상당한 메모리 할당이 필요합니다.)
안전상의 이유로 몇 가지 제한이 가해지고 있습니다. 명명된 변수가 그런 식으로 선언되더라도 결코 r값으로 간주되지 않습니다. r값을 얻으려면 함수 템플릿 std::move()
사용해야 합니다. Rvalue 참조는 이동 생성자와 함께 주로 사용하도록 설계된 특정 상황에서만 수정할 수도 있습니다.
rvalue 참조문구의 특성과 lvalue 참조문구(정규 참조문구)에 대한 일부 수정으로 인해 rvalue 참조문구는 개발자가 완벽한 기능 전달을 제공할 수 있습니다. 이 기능을 사용하면 변수 템플릿과 결합하면 특정 인수를 사용하는 다른 함수에 인수를 완벽하게 전달할 수 있는 함수 템플릿을 사용할 수 있습니다. 이것은 생성자 매개변수 전달, 특정 인수에 대해 올바른 생성자를 자동으로 호출하는 공장 함수를 만드는 데 가장 유용합니다. 이것은 C++ 표준 라이브러리 메소드의 emplace_back 집합에서 볼 수 있습니다.
constexp – 일반화된 상수식
C++는 항상 상수 표현이라는 개념을 가지고 있었습니다. 다음과 같은 표현입니다. 3+4
컴파일 시간과 실행 시간에서 항상 동일한 결과를 얻을 수 있습니다. 상수 표현식은 컴파일러의 최적화 기회이며, 컴파일러는 컴파일 시에 자주 실행하고 프로그램에서 결과를 하드코드합니다. 또한 C++ 사양은 여러 곳에서 상수식을 사용해야 합니다. 배열을 정의하려면 상수식이 필요하며 열거자 값은 상수식이어야 합니다.
그러나 함수 호출 또는 개체 생성자를 포함하는 상수 식을 허용한 적이 없습니다. 따라서 이와 같이 간단한 코드는 유효하지 않습니다.
인트의 get_5() {돌아가다 5;} 인트의 어떤_가치가 있는[get_5() + 7]; // 12개 정수의 배열을 만듭니다. 잘못된 형식의 C++
이것은 C++03에서는 유효하지 않았습니다. 왜냐하면 get_five() + 7
는 상수식이 아닙니다. C++03 컴파일러는 다음을 알 수 있는 방법이 없습니다. get_five()
실제로 실행 시 일정합니다. 이론적으로, 이 함수는 전역 변수에 영향을 줄 수 있고, 다른 비런타임 상수 함수를 호출할 수도 있습니다.
C++11이 키워드를 소개했습니다. constexpr
, 이를 통해 사용자는 함수나 객체 생성기가 컴파일 타임 상수임을 보장할 수 있습니다.[11] 위의 예는 다음과 같이 다시 쓸 수 있습니다.
정곡을 찌르다 인트의 get_5() {돌아가다 5;} 인트의 어떤_가치가 있는[get_5() + 7]; // 12개 정수의 배열을 만듭니다. 유효 C++11
이것은 컴파일러가 다음을 이해하고 확인할 수 있게 해줍니다. get_five()
컴파일 시간 상수입니다.
사용. constexpr
어떤 함수에 대해 그 함수가 할 수 있는 일에 몇 가지 제한을 가합니다. 첫째, 함수는 non-void return type을 가져야 합니다. 둘째, 함수 본체는 변수를 선언하거나 새로운 유형을 정의할 수 없습니다. 셋째, 본문에는 선언문, 무효문 및 단일 반환문만 포함될 수 있습니다. 인수 대체 후 반환문의 식이 상수 식을 생성할 수 있도록 인수 값이 존재해야 합니다.
C++11 이전에는 변수가 상수로 선언되고 상수식인 초기화자가 있으며 적분 또는 열거형인 경우에만 변수 값을 상수식에 사용할 수 있었습니다. C++11은 변수가 다음과 같이 정의된 경우 적분 또는 열거형이어야 한다는 제한을 제거합니다. constexpr
키워드:
정곡을 찌르다 두 배의 지구_중력_acce = 9.8; 정곡을 찌르다 두 배의 달_중력_acce = 지구_중력_acce / 6.0;
이러한 데이터 변수는 암묵적으로 상수이며 상수식이어야 하는 초기화자가 있어야 합니다.
사용자 정의 유형에서 상수 표현식 데이터 값을 구성하려면 다음을 사용하여 생성자를 선언할 수도 있습니다. constexpr
.a constexpr
생성자의 함수 본문은 선언문과 null 문만 포함할 수 있으며, 다음과 같이 변수를 선언하거나 유형을 정의할 수 없습니다. constexpr
기능. 인수 대체 후 클래스의 멤버를 상수 표현식으로 초기화하는 인수 값이 있어야 합니다. 그러한 유형의 파괴자는 사소한 것이어야 합니다.
다음이 있는 유형에 대한 복사 생성자 constexpr
생성자는 일반적으로 다음과 같이 정의되어야 합니다. constexpr
생성자, constexpr 함수에서 값을 기준으로 유형의 개체를 반환할 수 있도록 허용합니다. 복사 컨스트럭터, 연산자 과부하 등 클래스의 모든 멤버 함수는 다음과 같이 선언할 수 있습니다. constexpr
, constexpr 함수에 대한 요구 사항을 충족하는 한. 이를 통해 컴파일러는 컴파일 시 개체를 복사하고 개체에 대한 작업을 수행하는 등의 작업을 수행할 수 있습니다.
상수 표현식이 아닌 인수로 constexp 함수 또는 생성자를 호출하면 함수가 constexp되지 않은 것처럼 동작하며 결과 값은 상수 표현식이 아닙니다. 마찬가지로 constexpr 함수의 반환문에 있는 식을 주어진 호출에 대한 상수식으로 평가하지 않으면 결과는 상수식이 아닙니다.
constexpr
다르다 consteval
, C++20에 도입된 반면 후자는 항상 컴파일 시간 상수를 생성해야 합니다. constexpr
이 제한은 없습니다.
일반적인 오래된 데이터의 정의 수정
C++03에서 클래스 또는 구조는 POD(Plean Old Data) 유형으로 간주되기 위해 여러 규칙을 따라야 합니다. 이 정의에 맞는 유형은 C와 호환되는 객체 레이아웃을 생성하며 정적으로 초기화할 수도 있습니다. C++03 표준은 컴파일러가 프로그램을 받아들일 수 없는 기술적 이유가 없음에도 불구하고 C와 호환되거나 정적으로 초기화될 수 있는 유형에 대한 제한이 있습니다. 만약 누군가가 C++03 POD 유형을 만들고 비가상 멤버 함수를 추가한다면, 이 유형은 더 이상 POD 유형이 아닐 것이고 정적으로 초기화될 수 없습니다. 메모리 레이아웃이 변경되지 않았음에도 불구하고 C와 호환되지 않습니다.
C++11은 POD 개념을 사소한 개념과 표준 레이아웃이라는 두 가지 별개의 개념으로 나누어 POD 규칙 중 몇 가지를 완화했습니다.
사소한 유형은 정적으로 초기화할 수 있습니다. 또한 다음을 통해 데이터를 복사하는 것이 유효하다는 것을 의미합니다. memcpy
, 복사 생성기를 사용할 필요가 없습니다. 사소한 유형의 수명은 생성자가 완료된 경우가 아니라 해당 저장소가 정의될 때 시작됩니다.
사소한 클래스 또는 구조는 다음과 같은 것으로 정의됩니다.
- 사소한 기본 생성자가 있습니다. 기본 생성자 구문을 사용할 수 있습니다.
SomeConstructor() = default;
). - 기본 구문을 사용할 수 있는 사소한 복사 및 이동 생성기가 있습니다.
- 기본 구문을 사용할 수 있는 사소한 복사 및 이동 할당 연산자가 있습니다.
- 가상이 아니어야 하는 사소한 파괴자가 있습니다.
생성자는 클래스의 가상 멤버 함수가 없고 가상 기본 클래스가 없는 경우에만 사소합니다. 또한 복사/이동 작업을 수행하려면 정적이 아닌 모든 데이터 멤버가 사소한 것이어야 합니다.
표준 레이아웃 유형은 C와 호환되는 방식으로 구성원을 주문하고 포장하는 것을 의미합니다. 클래스 또는 구조는 정의에 따라 다음과 같은 표준 레이아웃입니다.
- 가상 기능이 없습니다.
- 가상 기본 클래스가 없습니다.
- 모든 비정형 데이터 구성원은 동일한 액세스 제어(공개, 비공개, 보호)를 가집니다.
- 기본 클래스를 포함하여 모든 비정형 데이터 멤버가 계층에서 동일한 하나의 클래스에 있습니다.
- 위 규칙은 모든 기본 클래스와 클래스 계층의 모든 비정규 데이터 멤버에도 적용됩니다.
- 처음 정의된 비정규 데이터 멤버와 동일한 유형의 기본 클래스가 없습니다.
클래스/구조/조합은 사소하고 표준 레이아웃이며 모든 비정규 데이터 멤버 및 기본 클래스가 POD인 경우 POD로 간주됩니다.
이러한 개념들을 분리함으로써 하나는 다른 하나를 잃지 않고 포기하는 것이 가능해집니다. 이동 및 복사 생성자가 복잡한 클래스는 사소하지 않을 수 있지만 표준 레이아웃이므로 C와 상호 작용할 수 있습니다. 마찬가지로, 퍼블릭 및 프라이빗 비정규 데이터 멤버가 있는 클래스는 표준 레이아웃은 아니지만 사소한 것일 수 있습니다. memcpy
-가능합니다.
핵심 언어 빌드 시간 성능 향상
외부 템플릿
C++03에서 컴파일러는 번역 단위에서 완전히 지정된 템플릿을 만날 때마다 템플릿을 인스턴스화해야 합니다. 템플릿이 여러 번역 단위에서 동일한 유형으로 인스턴스화되면 컴파일 시간이 크게 증가할 수 있습니다. C++03에서는 이를 막을 방법이 없으므로 C++11은 외부 데이터 선언과 유사한 외부 템플릿 선언을 도입했습니다.
C++03은 컴파일러가 템플릿을 인스턴스화하도록 의무화하는 구문을 가지고 있습니다.
템플릿 학급 std::벡터의<마이 클래스>;
C++11은 이제 다음 구문을 제공합니다.
외부의 템플릿 학급 std::벡터의<마이 클래스>;
이것은 컴파일러에게 이 번역 단위에서 템플릿을 인스턴스화하지 말라고 말합니다.
핵심 언어 사용성 향상
이러한 기능은 언어를 사용하기 쉽게 만드는 주요 목적으로 존재합니다. 이들은 유형 안전성을 향상시키고, 코드 반복을 최소화하며, 잘못된 코드의 가능성을 줄이는 등의 역할을 할 수 있습니다.
초기화자 목록
C++03은 C에서 이니셜라이저 목록 기능을 상속했습니다. 구조체 배열에는 구조체에서 구성원의 정의 순서대로 괄호 안의 인수 목록이 제공됩니다. 이러한 초기화자 목록은 재귀적이므로 다른 구조를 포함하는 구조나 구조 배열이 이를 사용할 수 있습니다.
짜임새 있는 물건 { 흘러가다 첫번째; 인트의 둘째; }; 물건 스칼라 = {0.43f, 10}; //첫 번째 = 0.43f, 두 번째 = 10인 객체 하나 물건 배열체[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; //세 개의 객체 배열
이것은 정적 목록이나 구조를 어떤 값으로 초기화하는 데 매우 유용합니다. C++는 개체를 초기화하는 생성자도 제공하지만 초기화자 목록만큼 편리하지 않은 경우가 많습니다. 그러나 C++03은 POD(Plain Old Data) 정의에 부합하는 구조와 클래스에만 초기화자 목록을 허용합니다. C++11은 초기화자 목록을 확장하므로 다음과 같은 표준 컨테이너를 포함한 모든 클래스에 사용할 수 있습니다. std::vector
.
C++11은 다음과 같은 템플릿에 개념을 바인딩합니다. std::initializer_list
. 이를 통해 생성자 및 기타 함수에서 초기화자 목록을 매개 변수로 사용할 수 있습니다. 예:
학급 시퀀스 클래스 { 일반의: 시퀀스 클래스(std::initializer_list<인트의> 목록.); };
이것은 허용합니다. SequenceClass
다음과 같은 정수열로 구성됩니다.
시퀀스 클래스 some_var = {1, 4, 5, 6};
이 생성자는 초기화자-리스트-생성자라고 하는 특수한 유형의 생성자입니다. 그러한 컨스트럭터가 있는 클래스는 균일한 초기화 동안 특별하게 취급됩니다(아래 참조).
템플릿 클래스 std::initializer_list<>
는 1등급 C++11 표준 라이브러리 유형입니다. C++11 컴파일러에 의해 정적으로 구성될 수 있습니다. {}
그런 괄호가 추론할 수 있는 문맥에서 형식 이름이 없는 구문 std::initializer_list
, 또는 다음과 같은 유형을 명시적으로 지정함으로써 std::initializer_list<SomeType>{args}
(다른 다양한 구성 구문의 경우에도 마찬가지입니다.)
목록은 일단 작성되면 복사할 수 있으며, 이는 값이 싸고 복사 기준(일반적으로 클래스는 시작/끝 포인터 쌍으로 구현됨)으로 작용합니다. An std::initializer_list
는 일정합니다. 구성원은 한 번 생성되면 변경할 수 없으며 구성원의 데이터도 변경할 수 없습니다(이는 구성원으로부터 이동하는 것을 배제하고 클래스 구성원으로 복사본을 필요로 하는 등).
비록 그 구성은 컴파일러에 의해 특별하게 취급되지만, std::initializer_list
실제 유형이므로 클래스 컨스트럭터 외에 다른 곳에서도 사용할 수 있습니다. 일반 함수는 입력할 수 있습니다. std::initializer_list
논고로서 예:
공허한 function_name(std::initializer_list<흘러가다> 목록.); // 복사는 저렴합니다. 위를 참조하십시오. function_name({1.0f, -3.45f, -0.4f});
표준 라이브러리의 예로는 다음이 있습니다. std::min()
그리고. std::max()
템플릿 가져오기 std::initializer_list
숫자형의
표준 용기는 다음과 같은 방법으로 초기화할 수도 있습니다.
std::벡터의<std::끈의> v = { "xyzy", "플러그", "abracadabra" }; std::벡터의<std::끈의> v({ "xyzy", "플러그", "abracadabra" }); std::벡터의<std::끈의> v{ "xyzy", "플러그", "abracadabra" }; // 아래 "Uniform initialization" 참조
균일한 초기화
C++03은 유형을 초기화하는 데 여러 가지 문제가 있습니다. 이를 수행하는 여러 가지 방법이 존재하며, 일부 방법은 상호 교환 시 다른 결과를 생성합니다. 예를 들어, 기존의 생성자 구문은 함수 선언처럼 보일 수 있으며, 컴파일러의 가장 성가신 구문 분석 규칙이 그런 것으로 착각하지 않도록 조치를 취해야 합니다. Aggregate 초기화기를 사용하여 Aggregate 및 POD 유형만 초기화할 수 있습니다(사용). SomeType var = {/*stuff*/};
).
C++11은 모든 객체에 대해 작동하는 완전한 균일한 유형 초기화를 허용하는 구문을 제공합니다. 초기화자 목록 구문에서 확장됩니다.
짜임새 있는 기본 구조 { 인트의 x; 두 배의 y; }; 짜임새 있는 알트 스트럭트 { 알트 스트럭트(인트의 x, 두 배의 y) : x_{x} , y_{y} {} 사적인: 인트의 x_; 두 배의 y_; }; 기본 구조 var1{5, 3.2}; 알트 스트럭트 var2{2, 4.3};
의 초기화 var1
애그리게이트 initial화인 것처럼 동작합니다. 즉, 개체의 각 데이터 멤버는 initializer-list에서 해당 값으로 복사 초기화됩니다. 필요한 경우 암시적 유형 변환이 사용됩니다. 변환이 없거나 좁은 변환만 존재하면 프로그램이 잘못 형성됩니다. 의 초기화 var2
생성자를 호출합니다.
다음과 같은 작업도 수행할 수 있습니다.
짜임새 있는 IdString { std::끈의 이름.; 인트의 식별자; }; IdString get_string() { 돌아가다 {"foo", 42}; //명시적 유형이 없음을 알려드립니다. }
균일한 초기화는 여전히 필요한 생성자 구문을 대체하지 않습니다. 클래스에 초기화자 목록 생성자가 있는 경우(TypeName(initializer_list<SomeType>);
), 초기화자 목록이 시퀀스 생성자의 유형과 일치하는 경우 다른 형식의 생성보다 우선합니다. C++11 버전의 std::vector
템플릿 유형에 대한 초기화자 목록 생성자가 있습니다. 따라서 이 코드는 다음과 같습니다.
std::벡터의<인트의> 화목한 사람{4};
의 생성자가 아닌 초기화자 목록 생성자를 호출합니다. std::vector
단일 크기 매개변수를 사용하여 해당 크기의 벡터를 만듭니다. 후자의 생성자에 액세스하려면 사용자가 표준 생성자 구문을 직접 사용해야 합니다.
유형추론
C++03(및 C)에서 변수를 사용하려면 변수의 유형을 명시적으로 지정해야 합니다. 그러나 템플릿 유형 및 템플릿 메타프로그래밍 기술의 출현으로 인해 어떤 것의 유형, 특히 함수의 잘 정의된 반환 값이 쉽게 표현되지 않을 수 있습니다. 따라서 변수에 중간체를 저장하는 것은 어렵기 때문에 주어진 메타프로그래밍 라이브러리의 내부에 대한 지식이 필요할 수 있습니다.
C++11은 두 가지 방법으로 이를 완화할 수 있습니다. 첫째, 명시적인 초기화를 가진 변수의 정의는 다음을 사용할 수 있습니다. auto
키워드[12][13] 그러면 초기화기의 특정 유형에 대한 변수가 생성됩니다.
오토 some_strange_콜 가능_타입 = std::결박시키다(&어떤_함수, _2, _1, 어떤_객체); 오토 기타_ = 5;
종류가. some_strange_callable_type
단순히 특정 템플릿 기능을 무시하는 것입니다. std::bind
특정 인수에 대한 수익을 얻을 수 있습니다. 이 유형은 의미 분석 작업의 일부로 컴파일러에 의해 절차적으로 쉽게 결정되지만 사용자가 검사할 때 쉽게 결정할 수 없습니다. 종류가. other_variable
또한 잘 정의되어 있지만 사용자가 더 쉽게 결정할 수 있습니다. 그것은 int
, 정수 리터럴과 같은 유형입니다.
이 키워드의 사용 auto
C++에서 이 키워드의 의미론은 원래 유형이 없는 이전 언어 B에서 유형이 없는 자동 변수 정의를 나타내는 관련 역할로 사용되었습니다.
게다가, 키워드는 decltype
컴파일 시 식 유형을 결정하는 데 사용할 수 있습니다. 예:
인트의 약간_int; 디클타입의(약간_int) 기타_integer_ = 5;
이것은 와 함께 사용하면 더 유용합니다. auto
, 자동 변수의 유형은 컴파일러에게만 알려져 있기 때문입니다. 하지만, decltype
또한 연산자 과부하 및 특수 유형을 많이 사용하는 코드의 표현에 매우 유용할 수 있습니다.
auto
또한 코드의 장황함을 줄이는 데 유용합니다. 예를 들어, 글을 쓰는 대신에
위해서 (std::벡터의<인트의>::const_iterator 그것의 = myvec.시작하다, 시작하다, 시작하다, 시작하다, 시작하다, 시작하다(); 그것의 != myvec.성씨가 좋은(); ++그것의)
프로그래머는 더 짧은 것을 사용할 수 있습니다.
위해서 (오토 그것의 = myvec.시작하다, 시작하다, 시작하다, 시작하다, 시작하다, 시작하다(); 그것의 != myvec.성씨가 좋은(); ++그것의)
"myvec"이 시작/종료자를 구현하기 때문에 더욱 압축할 수 있습니다.
위해서 (상투적인 오토& x : myvec)
이러한 차이는 프로그래머가 컨테이너를 둥지로 만들기 시작함에 따라 커지지만, 이러한 경우에는 typedef
코드의 양을 줄이는 좋은 방법입니다.
로 표시된 유형 decltype
에 의해 추론된 유형과 다를 수 있습니다. auto
.
# <vector> 인트의 주된() { 상투적인 std::벡터의<인트의> v(1); 오토 a = v[0]; // 활자가 있는 글자 디클타입의(v[0]) b = 1; // b는 type constint&, return type의 return type. // std::vector<int>::operator[](size_type) const 오토 c = 0; // chas type int 오토 d = c; // d는 typeint를 가지고 있습니다. 디클타입의(c) e; // e에는 c로 명명된 엔티티의 유형인 type int가 있습니다. 디클타입의((c)) f = c; // f는 (c)가 모두 값이기 때문에 int& 유형이 있습니다. 디클타입의(0) g; // g는 type int를 가지고 있습니다. 0은 r값이기 때문입니다. }
루프의 범위 기반
C++11은 의 구문을 확장합니다. for
요소 범위에 걸쳐 쉽게 반복할 수 있는 문장:
인트의 my_array[5] = {1, 2, 3, 4, 5}; // my_array의 각 요소 값을 두 배로 늘립니다. 위해서 (인트의& x : my_array) x *= 2; // 배열 요소에 대해 유사하지만 유형 추론을 사용하기도 함 위해서 (오토& x : my_array) x *= 2;
이런 형태의 for
, "range-based for"라고 불리며, 목록의 각 요소에 대해 반복됩니다. C-스타일 어레이, 초기화자 목록 및 모든 유형에서 작동합니다. begin()
그리고. end()
반복기를 반환하는 함수가 정의되었습니다. 시작/종료 쌍이 있는 모든 표준 라이브러리 컨테이너는 범위 기반 for 문과 함께 작동합니다.
람다 함수 및 식
C++11은 람다 함수라고 불리는 익명 함수를 생성하는 기능을 제공합니다.[14] 이는 다음과 같이 정의됩니다.
[](인트의 x, 인트의 y) -> 인트의 { 돌아가다 x + y; }
반환형()-> int
이 예제에서)는 모두 생략할 수 있습니다. return
식은 동일한 유형을 반환합니다. 람다는 선택적으로 클로저가 될 수 있습니다.
대체 함수 구문
표준 C 함수 선언 구문은 C 언어의 특징 집합에 완벽하게 적합했습니다. C++는 C에서 진화하면서 기본 구문을 유지하고 필요한 곳에서 확장했습니다. 그러나 C++가 복잡해짐에 따라 특히 템플릿 기능 선언과 관련하여 몇 가지 한계를 드러냈습니다. 예를 들어, C++03에서는 유효하지 않습니다.
템플릿<학급 Lhs, 학급 Rhs> 레트 추가_fun(상투적인 Lhs &lhs, 상투적인 Rhs &rhs) {돌아가다 lhs + rhs;} //ret는 lhs+rhs 유형이어야 합니다.
종류가. Ret
유형을 추가하는 것이 무엇이든 간에 Lhs
그리고. Rhs
생산할 것입니다. 앞서 언급한 C++11 기능을 사용하더라도 decltype
, 이것은 불가능합니다.
템플릿<학급 Lhs, 학급 Rhs> 디클타입의(lhs+rhs) 추가_fun(상투적인 Lhs &lhs, 상투적인 Rhs &rhs) {돌아가다 lhs + rhs;} //유효하지 않은 C++11
이것은 유효하지 않은 C++입니다. 그 이유는 lhs
그리고. rhs
아직 정의되지 않았습니다. 구문 분석기가 함수 프로토타입의 나머지 부분을 구문 분석할 때까지 유효한 식별자가 되지 않습니다.
이 문제를 해결하기 위해 C++11은 후행 반환형을 가진 새로운 함수 선언 구문을 도입했습니다.[15]
템플릿<학급 Lhs, 학급 Rhs> 오토 추가_fun(상투적인 Lhs &lhs, 상투적인 Rhs &rhs) -> 디클타입의(lhs+rhs) {돌아가다 lhs + rhs;}
이 구문은 더 일상적인 함수 선언 및 정의에 사용될 수 있습니다.
짜임새 있는 Some Struct { 오토 func_name(인트의 x, 인트의 y) -> 인트의; }; 오토 Some Struct::func_name(인트의 x, 인트의 y) -> 인트의 { 돌아가다 x + y; }
이 경우 "auto" 키워드를 사용하는 것은 구문의 일부일 뿐이며 C++11에서 자동 유형 추론을 수행하지 않습니다. 그러나 C++14부터는 후행 반환 형식을 완전히 제거할 수 있으며 컴파일러는 반환 형식을 자동으로 추론합니다.[16]
객체구축개선
C++03에서 클래스의 생성자는 해당 클래스의 초기화자 목록에 있는 다른 생성자를 호출할 수 없습니다. 각 생성자는 다음과 같이 클래스 멤버 자체를 구성하거나 공통 멤버 함수를 호출해야 합니다.
학급 일부 유형 { 일반의: 일부 유형(인트의 new_number) { 건설하다(new_number); } 일부 유형() { 건설하다(42); } 사적인: 공허한 건설하다(인트의 new_number) { 번호 = new_number; } 인트의 번호; };
기본 클래스에 대한 생성자는 파생 클래스에 직접 노출될 수 없습니다. 각 파생 클래스는 기본 클래스 생성자가 적합한 경우에도 생성자를 구현해야 합니다. 클래스의 비정수 데이터 멤버는 해당 멤버의 선언 현장에서 초기화할 수 없습니다. 생성기에서만 초기화할 수 있습니다.
C++11은 이 모든 문제에 대한 해결책을 제공합니다.
C++11을 사용하면 생성자가 다른 피어 생성자(일명 위임)를 호출할 수 있습니다. 이를 통해 생성자는 최소 추가된 코드로 다른 생성자의 동작을 활용할 수 있습니다. 위임은 자바, 목표-C와 같은 다른 언어에서 사용되었습니다.
이 구문은 다음과 같습니다.
학급 일부 유형 { 인트의 번호; 일반의: 일부 유형(인트의 new_number) : 번호(new_number) {} 일부 유형() : 일부 유형(42) {} };
이 경우, 다음과 같은 효과를 얻을 수 있었습니다. new_number
디폴트 파라미터 그러나 새로운 구문은 기본값(42)을 인터페이스가 아닌 구현에서 표현할 수 있도록 하는데, 이는 함수 매개변수에 대한 기본값이 호출 사이트에 "베이크 인"되기 때문에 라이브러리 코드의 유지관리자에게 이점이 됩니다. 반면, 생성자 위임은 라이브러리를 사용하여 코드를 다시 컴파일하지 않고도 값을 변경할 수 있습니다.
다음과 같은 주의 사항이 있습니다. C++03은 생성자가 실행을 완료하면 객체가 생성되는 것으로 간주하지만, C++11은 생성자가 실행을 완료하면 객체가 생성되는 것으로 간주합니다. 여러 개의 생성자를 실행할 수 있기 때문에, 이는 각 위임 생성자가 자신의 유형의 완전히 구성된 개체에 대해 실행된다는 것을 의미합니다. 파생 클래스 생성자는 기본 클래스의 모든 위임이 완료된 후 실행됩니다.
기본 클래스 생성자의 경우 C++11을 사용하면 클래스에서 기본 클래스 생성자가 상속됨을 지정할 수 있습니다. 따라서 C++11 컴파일러는 파생된 클래스의 상속 및 기본 클래스로의 전달을 수행하기 위한 코드를 생성합니다. 이 기능은 기본 클래스의 모든 생성자가 전달되거나 전달되지 않는 기능입니다. 또한 상속된 생성자가 파생된 클래스의 생성자의 서명과 일치하는 경우 쉐이딩되며 여러 상속에 대한 제한이 있습니다. 클래스 생성자는 동일한 서명을 사용하는 두 클래스에서 상속될 수 없습니다.
구문은 다음과 같습니다.
학급 기본 클래스 { 일반의: 기본 클래스(인트의 가치); }; 학급 파생 클래스 : 일반의 기본 클래스 { 일반의: 사용. 기본 클래스::기본 클래스; };
멤버 초기화를 위해 C++11은 다음 구문을 허용합니다.
학급 일부 클래스 { 일반의: 일부 클래스() {} 명시적 일부 클래스(인트의 new_value) : 가치(new_value) {} 사적인: 인트의 가치 = 5; };
클래스의 모든 구성자가 초기화합니다. value
5의 경우, 생성자가 초기화를 자신의 것으로 덮어쓰지 않는 경우. 따라서 위의 빈 컨스트럭터가 초기화됩니다. value
클래스 정의에 명시되어 있지만 int를 취하는 생성자가 지정된 매개 변수로 초기화합니다.
위에 표시된 할당 초기화 대신 생성자 또는 균일한 초기화를 사용할 수도 있습니다.
명시적 재지정 및 최종
C++03에서는 기본 클래스 함수를 재정의하려고 할 때 실수로 새로운 가상 함수를 생성할 수 있습니다. 예:
짜임새 있는 기초 { 가상의 공허한 어떤_재미있는(흘러가다); }; 짜임새 있는 파생된 : 기초 { 가상의 공허한 어떤_재미있는(인트의); };
다음과 같이 가정합니다. Derived::some_func
는 기본 클래스 버전을 대체하기 위한 것입니다. 대신 다른 서명을 가지고 있기 때문에 두 번째 가상 기능을 생성합니다. 이것은 특히 사용자가 기본 클래스를 수정할 때 흔히 발생하는 문제입니다.
C++11은 이 문제를 해결하기 위한 구문을 제공합니다.
짜임새 있는 기초 { 가상의 공허한 어떤_재미있는(흘러가다); }; 짜임새 있는 파생된 : 기초 { 가상의 공허한 어떤_재미있는(인트의) 덮어씌우다; // 잘못된 형식 - 기본 클래스 메서드를 재정의하지 않음 };
그 override
특수 식별자는 컴파일러가 기본 클래스(들)를 확인하여 이 정확한 서명을 가진 가상 함수가 있는지 확인하는 것을 의미합니다. 그리고 그렇지 않으면 컴파일러가 오류를 표시합니다.
C++11은 또한 클래스에서 상속을 방지하거나 파생 클래스에서 단순히 재정의되는 메서드를 방지하는 기능을 추가합니다. 이 작업은 특수 식별자로 수행됩니다. final
. 예:
짜임새 있는 베이스1 최종 { }; 짜임새 있는 파생1 : 베이스1 { }; // 클래스 Base1이 최종으로 표시되었기 때문에 잘못된 형식입니다.
짜임새 있는 베이스2 { 가상의 공허한 f() 최종; }; 짜임새 있는 파생2 : 베이스2 { 공허한 f(); // 가상 함수 Base2:::f가 최종으로 표시되었기 때문에 잘못된 형식입니다. };
이 예에서는 virtual void f() final;
문은 새 가상 함수를 선언하지만 파생 클래스가 이 함수를 재정의하지 못하도록 합니다. 또한 파생 클래스가 해당 특정 함수 이름 및 매개 변수 조합을 사용하지 못하도록 하는 효과도 있습니다.
둘 다 아니다. override
도 아니다 final
언어 키워드입니다. 이들은 기술적으로 선언자 특성의 식별자입니다.
- 이러한 특정 후행 컨텍스트에서 (모든 형식 지정자, 액세스 지정자, 구성원 선언자(구조, 클래스 및 열거형) 및 선언자 지정자 이후, 쉼표로 구분된 선언자 목록에서 각 선언자의 초기화 또는 코드 구현 전에만) 속성으로 특별한 의미를 얻을 수 있습니다.
- 이들은 선언된 형식 서명을 변경하지 않으며, 어떠한 범위에서도 새로운 식별자를 선언하거나 재정의하지 않습니다.
- 인식되고 허용된 선언자 속성은 C++의 미래 버전에서 확장될 수 있습니다(일부 컴파일러 고유 확장자는 이미 추가된 선언자 속성을 인식하고, 코드 생성 옵션이나 최적화 힌트를 컴파일러에 제공하거나, 디버거, 링커를 대상으로 하는 컴파일된 코드에 추가된 데이터를 생성하기 위해). 컴파일된 코드의 배포 또는 추가된 시스템 고유의 보안 속성을 제공하거나 런타임 시 반사 능력을 향상시키기 위해, 또는 다른 프로그래밍 언어 및 런타임 시스템과의 상호 운용성을 위해 추가된 바인딩 정보를 제공합니다. 이러한 확장은 선언자 속성 식별자 뒤에 괄호 사이의 매개 변수를 취할 수 있습니다. ANSI 적합성을 위해 이러한 컴파일러 고유 확장은 이중 밑줄 접두사 규칙을 사용해야 합니다.
- 다른 위치에서는 새 선언에 유효한 식별자가 될 수 있습니다(그리고 나중에 액세스할 수 있는 경우 사용).
Null 포인터 상수 및 유형
본 섹션과 본 섹션의 목적만을 위해 "의 모든 발생"을 수행합니다.0
” 는 "평가하는 일정한 표현"으로 의미됩니다. 0
, 이는 int"형입니다. 실제로 상수 표현식은 어떤 적분 형식도 될 수 있습니다.
1972년 C의 새벽부터 상수는 0
는 정수 상수와 널 포인터 상수의 이중 역할을 했습니다. 의 이중적 의미에 내재된 모호성은 0
전처리기 매크로를 사용하여 C에서 처리했습니다. NULL
, 일반적으로 둘 중 하나로 확장됩니다. ((void*)0)
아니면 0
. C++에서 암묵적 변환을 금지합니다. void *
다른 포인터 유형으로, 따라서 캐스팅의 이점을 제거합니다. 0
로. void *
. 결과적으로, 오직, 0
null 포인터 상수로 허용됩니다. 이는 기능 과부하와 상호 작용이 잘 되지 않습니다.
공허한 푸우(촤 *); 공허한 푸우(인트의);
한다면 NULL
다음과 같이 정의됩니다. 0
(일반적으로 C++의 경우에 해당), 문장 foo(NULL);
전화를 걸 것입니다. foo(int)
, 프로그래머가 의도한 것도 아니고, 코드를 피상적으로 읽는 것도 아닙니다.
C++11은 구별된 널 포인터 상수로 사용할 새로운 키워드를 도입하여 이를 수정합니다. nullptr
. 유형입니다. nullptr_t
, 이는 암묵적으로 변환 가능하며 모든 포인터 유형 또는 포인터 대 멤버 유형과 비교할 수 있습니다. 다음을 제외하고는 암묵적으로 변환 가능하거나 적분 유형과 비교할 수 없습니다. bool
. 원래 제안서에 유형의 r값이 명시되어 있는 반면 nullptr_t
로 전환할 수 없습니다. bool
, 핵심 언어 작업 그룹은 일반 포인터 유형과의 일관성을 위해 그러한 변환이 바람직하다고 결정했습니다. 제안된 문구 변경 사항은 2008년 6월에 만장일치로 워킹 페이퍼(Working Paper)에 투표되었습니다.[2] C 표준 작업 그룹에도 비슷한 제안이 들어왔고 C23에 포함되도록 승인되었습니다.[17]
하위 호환성의 이유로, 0
유효한 널 포인터 상수를 유지합니다.
촤 *pc = nullptr; // 오케이. 인트의 *파이 = nullptr; // 오케이. 흥얼거리다 b = nullptr; // 알겠습니다. b는 거짓입니다. 인트의 i = nullptr; // 과오 푸우(nullptr); // foo(int)가 아닌 foo(nullptr_t)를 호출합니다. /* 위의 예제에서 foo(nullptr_t)는 실제로 foo(char *)를 암묵적 변환을 사용하여 호출합니다. 범위에서 호환되는 포인터 유형으로 오버로드되는 다른 함수가 없는 경우에만 해당됩니다. 과적이 여러 개 존재할 경우, 그 해결이 모호하여 실패하고, 명시적인 foo(foo) 선언이 없는 한( nullptr_t). C++11에 대한 표준 유형 헤더에서 nullptr_t 유형은 다음과 같이 선언되어야 합니다. def dectype( nullptr) nullptr_t; 그러나 다음과 같은 경우는 아닙니다. null을 0으로 정의해야 하는 C++ 이전 버전의 defint nullptr_t; // 이전 버전의 null을 0으로 정의해야 함 def void *nullptr_t; // NULL을 (void*)0으로 정의하는 ANSI C를 입력합니다. */
강력하게 입력된 열거형
C++03에서 열거형은 유형 안전하지 않습니다. 열거 유형이 서로 다른 경우에도 효과적으로 정수입니다. 이렇게 하면 서로 다른 열거 유형의 두 열거 값을 비교할 수 있습니다. C++03이 제공하는 유일한 안전성은 정수 또는 하나의 열거형 값이 다른 열거형으로 암시적으로 변환되지 않는다는 것입니다. 또한 기본적인 적분 유형은 구현 정의이므로 열거의 크기에 따라 달라지는 코드는 휴대가 불가능합니다. 마지막으로 열거값은 엔클로저 범위로 범위가 지정됩니다. 따라서 같은 범위에 있는 두 개의 개별 열거형이 일치하는 멤버 이름을 가질 수 없습니다.
C++11은 이러한 문제가 없는 열거의 특별한 분류를 허용합니다. 이것은 다음을 사용하여 표현됩니다. enum class
(enum struct
동의어로도 인정됨) 선언:
열거한 학급 열거 { 발1, 발2, 발3 = 100, 발4 // = 101 };
이 열거는 유형 안전합니다. 열거 클래스 값은 암시적으로 정수로 변환되지 않습니다. 따라서 이들은 정수(식)와도 비교할 수 없습니다. Enumeration::Val4 == 101
컴파일 오류를 제공합니다.
열거 클래스의 기본 유형은 항상 알려져 있습니다. 기본 유형은 다음과 같습니다. int
; 이 예에서 볼 수 있는 것처럼 다른 적분 유형으로 재정의할 수 있습니다.
열거한 학급 열거2 : 서명이 없는 인트의 {발1, 발2};
이전 스타일의 열거를 사용하면 값이 외부 범위에 배치됩니다. 새 스타일 열거를 사용하면 열거 클래스 이름의 범위 내에 배치됩니다. 그래서 위 예에서는. Val1
정의되지 않았지만 Enum2::Val1
정의되어 있습니다.
또한 이전 스타일의 열거가 명시적인 범위 지정을 제공할 수 있도록 하는 과도 구문이 있으며, 기본 유형의 정의는 다음과 같습니다.
열거한 열거3 : 서명이 없는 긴 {발1 = 1, 발2};
이 경우 열거자 이름은 열거자의 범위에 정의됩니다(Enum3::Val1
), 그러나 하위 호환성을 위해 그것들은 또한 엔클로저 범위에 배치됩니다.
C++11에서도 전진 선언 에넘이 가능합니다. 이전에는 열거의 크기가 구성원의 정의에 따라 달라지기 때문에 열거 유형을 순방향으로 선언할 수 없었습니다. 열거의 크기를 암시적으로 또는 명시적으로 지정하는 한, 그것은 순방향으로 선언될 수 있습니다.
열거한 열거1; // C++03 및 C++11에서 유효하지 않습니다. 기본 유형을 확인할 수 없습니다. 열거한 열거2 : 서명이 없는 인트의; // C++11에서 유효하며 기본 유형이 명시적으로 지정됩니다. 열거한 학급 열거3; // C++11에서 유효하며 기본 유형은 int입니다. 열거한 학급 열거4 : 서명이 없는 인트의; // C++11에서 유효합니다. 열거한 열거2 : 서명이 없는 짧다; // Enum2가 이전에 다른 기본 형식으로 선언되었기 때문에 C++11에서 잘못되었습니다.
직각브라켓
C++03 의 파서는 ""를 정의합니다.>>
” 모든 경우에 오른쪽 시프트 연산자 또는 스트림 추출 연산자로서. 그러나 중첩 템플릿 선언에서는 프로그래머가 두 개의 직각 괄호 사이에 공백을 두는 것을 소홀히 하는 경향이 있으므로 컴파일러 구문 오류가 발생합니다.
C++11은 구문 분석기의 사양을 개선하여 여러 개의 직각 괄호가 합리적인 템플릿 인수 목록을 닫는 것으로 해석됩니다. 매개 변수 식 주위에 괄호를 사용하여 ""를 사용하여 이를 재정의할 수 있습니다.>
”, “>=
” 아니면 ">>
” 이진 연산자:
템플릿<흥얼거리다 시험> 학급 일부 유형; std::벡터의<일부 유형<1>2>> x1; // std::SomeType<true>의 벡터로 해석됩니다. // "2 > > x1" 뒤에 오는 "2 > x1"은 선언자에게 유효한 구문이 아닙니다. 1은 맞습니다. std::벡터의<일부 유형<(1>2)>> x1; // std::SomeType<false>의 벡터로 해석됩니다. // 선언자 "x1" 뒤에 오는 것은 유효한 C++11 구문입니다. (1>2)는 false입니다.
명시적 변환 연산자
C++98 이 추가되었습니다. explicit
단일 argument 생성자가 암시적 형식 변환 연산자로 사용되는 것을 방지하기 위해 생성자의 수식자로 키워드를 지정합니다. 그러나 이는 실제 변환 운영자에게는 아무런 도움이 되지 않습니다. 예를 들어, 스마트 포인터 클래스는 다음을 가질 수 있습니다. operator bool()
기본 포인터와 같은 역할을 할 수 있도록 하기 위해: 이 변환을 포함하면 테스트할 수 있습니다. if (smart_ptr_variable)
(포인터가 null이 아닌 경우 true이고 그렇지 않은 경우 false입니다.) 그러나 이를 통해 다른 의도하지 않은 변환도 가능합니다. 왜냐하면 C++ bool
는 산술 유형으로 정의되며, 사용자가 의도하지 않은 수학적 연산을 허용하는 적분 또는 부동 소수점 유형으로 암묵적으로 변환될 수 있습니다.
C++11에서, explicit
키워드를 변환 연산자에 적용할 수 있습니다. 생성자와 마찬가지로 암묵적 변환에서 이러한 변환 함수를 사용하는 것을 방지합니다. 그러나 특히 부울 값(if-문과 루프의 조건, 논리 연산자에 대한 피연산자)이 필요한 언어 컨텍스트는 명시적 변환으로 계산되므로 부울 변환 연산자를 사용할 수 있습니다.
예를 들어, 이 기능은 안전한 부울 문제를 깨끗하게 해결합니다.
템플릿 별칭
C++03에서는 모든 실제 템플릿 인수가 지정된 템플릿 전문화의 동의어를 포함하여 다른 유형의 동의어로만 typeef를 정의할 수 있습니다. typedef 템플릿을 만들 수 없습니다. 예:
템플릿 <활자명 첫번째, 활자명 둘째, 인트의 셋째> 학급 일부 유형; 템플릿 <활자명 둘째> 타이프디프 일부 유형<기타 유형, 둘째, 5> typeefName; // C++03에서 유효하지 않음
컴파일되지 않습니다.
C++11은 다음 구문으로 이 기능을 추가합니다.
템플릿 <활자명 첫번째, 활자명 둘째, 인트의 셋째> 학급 일부 유형; 템플릿 <활자명 둘째> 사용. typeefName = 일부 유형<기타 유형, 둘째, 5>;
그 using
구문은 C++11에서 타입 앨리어싱으로도 사용할 수 있습니다.
타이프디프 공허한 (*기능.유형)(두 배의); // 올드스타일 사용. 기능.유형 = 공허한 (*)(두 배의); // 새로 도입된 구문
자유노조
C++03에서는 어떤 종류의 객체가 a의 멤버가 될 수 있는지에 대한 제한이 있습니다. union
. 예를 들어, 결합에는 중요하지 않은 생성자 또는 소멸자를 정의하는 개체가 포함될 수 없습니다. C++11은 이러한 제한 사항 중 일부를 해제합니다.[3]
만약에 union
멤버는 사소하지 않은 특수 멤버 함수를 가지고 있습니다. 컴파일러는 다음과 같은 멤버 함수를 생성하지 않습니다. union
수동으로 정의해야 합니다.
다음은 C++11에서 허용되는 조합의 간단한 예입니다.
# <새> // '새로운' 배치에 필요합니다. 짜임새 있는 포인트 { 포인트() {} 포인트(인트의 x, 인트의 y): x_(x), y_(y) {} 인트의 x_, y_; }; 연합의 U { 인트의 z; 두 배의 w; 포인트 p; // C++03에서는 유효하지 않으며 C++11에서는 유효합니다. U() {} // 점 부재로 인해 이제 생성자 정의가 필요합니다. U(상투적인 포인트& pt) : p(pt) {} // initializer list를 사용하여 Point 객체를 구성합니다. U& 교환입니다.=(상투적인 포인트& pt) { 신규(&p) 포인트(pt); 돌아가다 *이것.; } // 배치 '새'를 사용하여 점 객체를 할당합니다. };
변경 사항은 현재 규칙만 완화하기 때문에 기존 코드를 깨지 않습니다.
핵심 언어 기능 향상
이러한 기능을 통해 언어는 이전에는 불가능하거나 지나치게 방대하거나 이동이 불가능한 라이브러리가 필요한 작업을 수행할 수 있습니다.
버라이어티 템플릿
C++11에서 템플릿은 가변 수의 템플릿 매개 변수를 취할 수 있습니다. 또한 유형 안전 변수 함수를 정의할 수 있습니다.
새 문자열 리터럴
C++03은 두 종류의 스트링 리터럴을 제공합니다. 큰따옴표 안에 포함된 첫 번째 종류는 null-terminated 배열의 유형을 생성합니다. const char
. 정의된 두 번째 종류는 L""
, null-terminated 배열의 유형을 생성합니다. const wchar_t
,어디에 wchar_t
정의되지 않은 크기와 의미론의 넓은 문자입니다. 어떤 리터럴 타입도 UTF-8, UTF-16, 또는 다른 종류의 유니코드 인코딩이 있는 문자열 리터럴을 지원하지 않습니다.
C++11은 UTF-8, UTF-16, UTF-32의 세 가지 유니코드 인코딩을 지원합니다. 유형의 정의 char
적어도 UTF-8의 8비트 코딩을 저장하는 데 필요한 크기이며 컴파일러의 기본 실행 문자 집합의 구성원을 포함할 수 있을 만큼 충분히 크다는 것을 명시적으로 표현하기 위해 수정되었습니다. 이전에는 C++ 표준 자체에서 후자로만 정의되었으며, 이후 C 표준에 의존하여 최소 8비트를 보장합니다. 또한 C++11은 다음과 같은 두 가지 새로운 문자 유형을 추가합니다. char16_t
그리고. char32_t
. 이들은 각각 UTF-16과 UTF-32를 저장하도록 설계되었습니다.
지원되는 각 인코딩에 대해 문자열 리터럴을 생성하는 방법은 다음과 같습니다.
u8"I'm a UTF-8 string." u"이것은 UTF-16 현입니다." U"이것은 UTF-32 현입니다."
첫 번째 문자열의 유형은 일반적인 것입니다. const char[]
. 두번째 문자열의 종류는 const char16_t[]
(소문자 'u' 접두사)를 참고합니다. 세번째 문자열의 종류는 const char32_t[]
(대소문자 'U' 접두사).
유니코드 문자열 리터럴을 구축할 때 유니코드 코드 포인트를 문자열에 직접 삽입하는 것이 유용한 경우가 많습니다. 이를 위해 C++11은 다음 구문을 허용합니다.
u8"이것은 유니코드 문자입니다. \u2018." u"이것은 더 큰 유니코드 문자입니다. \u2018." U"이것은 유니코드 문자입니다. \U00002018."
다음 번호. \u
는 16진수입니다. 일반적인 숫자가 필요하지 않습니다. 0x
접두어의 식별자가. \u
는 16비트 유니코드 코드 포인트를 나타냅니다. 32비트 코드 포인트를 입력하려면, \U
그리고 32비트 16진수입니다. 유효한 유니코드 코드 포인트만 입력할 수 있습니다. 예를 들어 U+D800–U+DFFF 범위의 코드 포인트는 UTF-16 인코딩에서 대리 쌍을 위해 예약되어 있으므로 금지됩니다.
특히 XML 파일의 리터럴, 스크립트 언어 또는 정규 표현식을 사용할 때는 수동으로 문자열을 빠져나가는 것을 피하는 것이 유용하기도 합니다. C++11은 원시 문자열 리터럴을 제공합니다.
R(The String Data \ String " \ String " )" R" 한정자(The String Data \ String " )" 한정자)
첫 번째 경우에는, 그 사이의 모든 것이 "(
그리고 그 )"
문자열의 일부입니다. 그 "
그리고. \
문자는 탈출할 필요가 없습니다. 두 번째 경우는. "delimiter(
문자열을 시작하고, 다음과 같은 경우에만 종료됩니다. )delimiter"
도달했습니다. 줄이. delimiter
빈 문자열을 포함하여 최대 16자 길이의 모든 문자열을 사용할 수 있습니다. 이 문자열은 공백, 컨트롤 문자를 포함할 수 없습니다. (
, )
, 또는 그 \
성격. 이 구분 기호 문자열을 사용하여 사용자가 시퀀스를 가질 수 있습니다. )"
미가공 문자열 리터럴 안에. 예를들면, R"delimiter("(a-z)")delimiter"
다음과 같습니다. "\"(a-z)\""
.
원시 문자열 리터럴은 넓은 리터럴 또는 유니코드 리터럴 접두사와 결합할 수 있습니다.
u8R"XXX(I'm a "raw UTF-8" string.)XXX"uR"*("raw UTF-16" 문자열입니다.)*" UR("raw UTF-32" 문자열입니다.)
사용자 정의 리터럴
C++03은 여러 리터럴을 제공합니다. 캐릭터들이. 12.5
컴파일러에 의해 유형으로 해결되는 리터럴입니다. double
값은 12.5입니다. 그러나 접미사의 추가는 f
, 와 같이 12.5f
, 유형 값을 만듭니다. float
값은 12.5입니다. 리터럴의 접미사 수식자는 C++ 규격에 의해 고정되며 C++03 코드는 새로운 리터럴 수식자를 만들 수 없습니다.
대조적으로, C++11은 사용자가 리터럴이 수정하는 문자의 문자열을 기반으로 객체를 구성할 새로운 종류의 리터럴 수식자를 정의할 수 있도록 합니다.
리터럴의 변환은 날것과 조리된 두 단계로 재정의됩니다. 원시 리터럴은 특정 유형의 문자 시퀀스인 반면 조리된 리터럴은 별도의 유형입니다. C++ 리터럴 1234
, 원시 리터럴로, 이 문자 시퀀스가 맞습니까? '1'
, '2'
, '3'
, '4'
. 조리된 문자 그대로 정수 1234입니다. C++ 리터럴 0xA
날것의 형태로는 '0'
, 'x'
, 'A'
, 조리된 형태일 때는 정수 10입니다.
리터럴은 조리된 형태로만 처리할 수 있는 스트링 리터럴을 제외하고 날것과 조리된 형태 모두로 확장할 수 있습니다. 이 예외는 문자열에 해당 문자의 특정 의미와 유형에 영향을 미치는 접두사가 있기 때문입니다.
사용자 정의 리터럴은 모두 접미사이므로 접미사 리터럴을 정의할 수 없습니다. 밑줄()을 제외한 모든 문자로 시작하는 접미사_
)는 표준에 따라 예약됩니다. 따라서 모든 사용자 정의 리터럴에는 밑줄로 시작하는 접미사가 있어야 합니다._
).[18]
리터럴의 원시 형태를 처리하는 사용자 정의 리터럴은 리터럴 연산자를 통해 정의되며, 다음과 같이 기록됩니다. operator ""
. 예는 다음과 같습니다.
출력 유형 교환입니다. "" _나의 서픽스(상투적인 촤 * 리터럴_스트링) { // OutputType에 constar를 사용하는 constructor가 있다고 가정합니다 * 출력 유형 레트(리터럴_스트링); 돌아가다 레트; } 출력 유형 어떤_ = 1234_나의 서픽스; // OutputType에 두 배를 반환하는 get_value() 메서드가 있다고 가정합니다. 주장하다(어떤_.get_value() == 1234.0)
과제명세서 OutputType some_variable = 1234_mysuffix;
사용자 정의 리터럴 함수에 의해 정의된 코드를 실행합니다. 이 기능은 통과되었습니다. "1234"
C-스타일 문자열이므로 null 종결자가 있습니다.
정수 및 부동 소수점 원시 리터럴을 처리하기 위한 다른 메커니즘은 가변 템플릿을 사용하는 것입니다.
템플릿<촤...> 출력 유형 교환입니다. "" _튜픽스(); 출력 유형 어떤_ = 1234_튜픽스; 출력 유형 또 다른_ = 2.17_튜픽스;
이것은 문자 그대로의 처리 기능을 다음과 같이 인스턴스화합니다. operator "" _tuffix<'1', '2', '3', '4'>()
. 이 양식에는 문자열을 종료하는 null 문자가 없습니다. 이 작업의 주요 목적은 C++11의 것을 사용하는 것입니다. constexpr
컴파일러가 컴파일 시에 리터럴을 완전히 변환할 수 있도록 하는 키워드입니다. OutputType
는 constexpress-copyable 및 copyable type이며, 리터럴 처리 함수는 constexpr
기능.
숫자 리터럴의 경우 조리된 리터럴의 유형은 다음 중 하나입니다. unsigned long long
일체형 리터럴의 경우 또는 long double
부동 소수점 리터럴의 경우(참고: 부호 접두사가 붙은 리터럴은 부호를 단칭 접두사 연산자로 포함하고 부호 없는 숫자를 포함하는 식으로 구문 분석되므로 부호 적분 형식이 필요하지 않습니다.) 대체 템플릿 양식이 없습니다.
출력 유형 교환입니다. "" _(서명이 없는 긴 긴); 출력 유형 교환입니다. "" _(긴 두 배의); 출력 유형 어떤_ = 1234_; // '부호가 긴' 과부하를 사용합니다. 출력 유형 또 다른_ = 3.1416_; // '긴 이중' 과부하를 사용합니다.
앞에서 언급한 새로운 문자열 접두사에 따라 문자열 리터럴의 경우 다음이 사용됩니다.
출력 유형 교환입니다. "" _s서픽스(상투적인 촤 * string_values, size_t num_chars); 출력 유형 교환입니다. "" _s서픽스(상투적인 wchar_t * string_values, size_t num_chars); 출력 유형 교환입니다. "" _s서픽스(상투적인 char16_t * string_values, size_t num_chars); 출력 유형 교환입니다. "" _s서픽스(상투적인 char32_t * string_values, size_t num_chars); 출력 유형 어떤_ = "1234"_s서픽스; // constchar *' 과부하를 사용합니다. 출력 유형 어떤_ = u8"1234"_s서픽스; // constchar *' 과부하를 사용합니다. 출력 유형 어떤_ = L"1234"_s서픽스; // const wchar_t *'오버로드를 사용합니다. 출력 유형 어떤_ = u"1234"_s서픽스; // constchar16_t *'오버로드를 사용합니다. 출력 유형 어떤_ = U"1234"_s서픽스; // constchar32_t *'오버로드를 사용합니다.
대체 템플릿 양식이 없습니다. 문자 리터럴도 유사하게 정의됩니다.
멀티쓰레딩 메모리 모델
C++11은 멀티 스레드 프로그래밍 지원을 표준화합니다.
프로그램에 여러 스레드가 공존할 수 있는 메모리 모델과 스레드 간 상호 작용을 위한 라이브러리 지원 두 부분이 관련되어 있습니다. (이 기사의 나사산 설비에 대한 섹션을 참조하십시오.)
메모리 모델은 여러 스레드가 동일한 메모리 위치에 액세스할 수 있는 경우를 정의하고 한 스레드의 업데이트가 다른 스레드에 표시되는 경우를 지정합니다.
스레드 로컬 스토리지
다중 스레드 환경에서는 모든 스레드에 고유한 변수가 있는 것이 일반적입니다. 이것은 함수의 로컬 변수에 대해서는 이미 발생하지만 전역 및 정적 변수에 대해서는 발생하지 않습니다.
스토리지 지정자가 새로운 스레드-로컬 스토리지 기간(기존의 정적, 동적 및 자동에 추가)을 표시합니다. thread_local
.
정적 저장 기간(즉, 프로그램의 전체 실행에 걸쳐 있는 수명)을 가질 수 있는 객체에는 스레드-로컬 기간이 대신 주어질 수 있습니다. 목적은 다른 정적 기간 변수와 마찬가지로 생성자를 사용하여 스레드 로컬 객체를 초기화하고 생성자를 사용하여 파괴할 수 있다는 것입니다.
명시적으로 기본화된 특수 멤버 함수
C++03에서 컴파일러는 자신이 제공하지 않는 클래스의 경우 기본 컨스트럭터, 복사 컨스트럭터, 복사 할당 연산자를 제공합니다.operator=
), 파괴자. 프로그래머는 사용자 정의 버전을 정의하여 이러한 기본값을 재정의할 수 있습니다. C++는 또한 다음과 같은 여러 전역 연산자를 정의합니다. operator new
프로그래머가 재정의할 수 있는 모든 클래스에 대해 작동합니다.
그러나 이러한 기본값을 만드는 것에 대한 제어는 거의 없습니다. 예를 들어 클래스를 본질적으로 복사할 수 없도록 만드는 것은 개인 복사 생성자 및 복사 할당 연산자를 선언하고 정의하지 않음으로써 수행될 수 있습니다. 이러한 기능을 사용하려고 시도하는 것은 ODR(One Definition Rule)을 위반하는 것입니다. 진단 메시지는 필요하지 [19]않지만 위반할 경우 링커 오류가 발생할 수 있습니다.
기본 생성자의 경우 클래스가 생성자로 정의된 경우 컴파일러가 기본 생성자를 생성하지 않습니다. 이것은 많은 경우에 유용하지만, 전문 컨스트럭터와 컴파일러 생성 기본값을 둘 다 가질 수 있는 것도 유용합니다.
C++11은 이러한 특수 멤버 함수의 명시적인 기본 설정 및 삭제를 허용합니다.[20] 예를 들어, 이 클래스는 기본 생성자를 사용할 수 있음을 명시적으로 선언합니다.
학급 일부 유형 { 일부 유형() = 체납; //기본 생성자가 명시적으로 명시되어 있습니다. 일부 유형(기타 유형 가치); };
명시적으로 삭제된 함수
함수를 명시적으로 비활성화할 수 있습니다. 이는 암시적 유형 변환을 방지하는 데 유용합니다. 그 = delete
특정 매개 변수 유형이 있는 함수를 호출하지 않도록 지정자를 사용할 수 있습니다.[20] 예:
공허한 노인트(두 배의 i); 공허한 노인트(인트의) = 지우다;
호출 시도 noInt()
와 함께 int
매개 변수는 컴파일러에 의해 자동 변환을 수행하는 대신 거부됩니다. double
.부르기 noInt()
와 함께 float
아직도 작동합니다.
이외의 다른 유형으로 함수를 호출하는 것을 금지할 수 있습니다. double
템플릿을 사용하여:
두 배의 온리 더블(두 배의 d) {돌아가다 d;} 템플릿<활자명 T> 두 배의 온리 더블(T) = 지우다;
부르기 onlyDouble(1.0)
효과가 있을 것입니다. onlyDouble(1.0f)
컴파일러 오류가 발생합니다.
클래스 멤버 함수 및 생성자도 삭제할 수 있습니다. 예를 들어, 복사 생성기를 삭제하여 클래스 객체를 복사하는 것을 방지할 수 있습니다. operator =
:
학급 복사 불가능 { 복사 불가능(); 복사 불가능(상투적인 복사 불가능&) = 지우다; 복사 불가능& 교환입니다.=(상투적인 복사 불가능&) = 지우다; };
유형 long long int
C++03에서 가장 큰 정수형은 long int
. 최소 사용 가능한 비트 수만큼 보장됩니다. int
. 이것은 결과적으로 long int
일부 인기 있는 구현에서는 64비트, 다른 구현에서는 32비트 크기를 갖습니다. C++11이 새 정수 유형을 추가합니다. long long int
이 문제를 해결하기 위해. 적어도 다음과 같은 크기로 보장됩니다. long int
, 64비트 이상입니다. 이 유형은 원래 표준 C에 C99가 도입했으며 대부분의 C++ 컴파일러가 이미 확장으로 지원했습니다.[21][22]
정적 주장
C++03은 주장을 테스트하는 두 가지 방법을 제공합니다: 매크로 assert
그리고 전처리기 명령어. #error
. 그러나 둘 다 템플릿에서 사용하기에는 적절하지 않습니다. 매크로는 실행 시간에 어설션을 테스트하는 반면 전처리 명령은 템플릿을 인스턴스화하기 전에 수행되는 전처리 중에 어설션을 테스트합니다. 템플릿 매개변수에 의존하는 속성을 테스트하는 데는 둘 다 적합하지 않습니다.
새로운 유틸리티는 컴파일 시에 새로운 키워드를 사용하여 주장을 테스트하는 새로운 방법을 도입합니다. static_assert
. 선언문은 다음과 같은 형태를 상정하고 있습니다.
static_assert(constant-express, 오류-message);
다음은 방법의 몇 가지 예입니다. static_assert
사용할 수 있습니다.
정적_((그리스피 > 3.14) && (그리스피 < 3.15), "GREIC PI는 부정확합니다!");
템플릿<학급 T> 짜임새 있는 확인. { 정적_(크기의(인트의) <= 크기의(T), "T는 충분히 크지 않습니다!"); };
템플릿<학급 적분> 적분 푸우(적분 x, 적분 y) { 정적_(std::is_<적분>::가치, "푸우 () 매개 변수는 필수 유형이어야 합니다."); }
상수식이 다음과 같을 때 false
컴파일러가 오류 메시지를 생성합니다. 첫 번째 예는 전처리기 명령어와 유사합니다. #error
, 전처리기는 통합형만 지원합니다.[23] 대조적으로, 두 번째 예제에서는 템플릿 클래스의 모든 인스턴스화에서 주장을 확인합니다. Check
.
정적 인수는 템플릿 외부에서도 유용합니다. 예를 들어, 알고리즘의 주어진 구현은 다음의 크기에 따라 달라질 수 있습니다. long long
보다 큰 int
, 표준이 보장하지 않는 것. 이와 같은 가정은 대부분의 시스템과 컴파일러에서 유효하지만, 전부는 아닙니다.
허락하다 sizeof
명시적인 목적 없이 학급의 구성원들을 대상으로 작업하다
C++03에서, sizeof
연산자는 유형 및 개체에 사용할 수 있습니다. 그러나 이를 수행하는 데 사용할 수는 없습니다.
짜임새 있는 일부 유형 { 기타 유형 구성원; }; 크기의(일부 유형::구성원); // C++03에서는 작동하지 않습니다. C++11로 OK
크기를 반환해야 합니다. OtherType
. C++03은 이를 허용하지 않으므로 컴파일 오류입니다. C++11 허용. 다음의 경우에도 허용됩니다. alignof
C++11에 도입된 연산자.
객체 정렬 제어 및 쿼리
C++11을 사용하여 변수 정렬을 쿼리하고 제어할 수 있습니다. alignof
그리고. alignas
.
그 alignof
연산자는 유형을 가져다가 유형 인스턴스가 할당되어야 하는 2바이트 경계의 거듭제곱을 반환합니다(예: std::size_t
). 기준 유형이 주어졌을 때 alignof
참조된 유형의 정렬을 반환하고 배열의 경우 요소 유형의 정렬을 반환합니다.
그 alignas
지정기는 변수의 메모리 정렬을 제어합니다. 지정자는 상수 또는 유형을 취합니다. 유형이 제공되면 alignas(T)
의 줄임말 alignas(alignof(T))
. 예를 들어, 문자 배열이 플로트를 고정하도록 적절하게 정렬되도록 지정하려면 다음과 같이 하십시오.
로 정렬하다.(흘러가다) 서명이 없는 촤 c[크기의(흘러가다)]
가비지 수집 구현 허용
프로그래머 주도의 쓰레기 수집을 위해 제공된 이전 C++ 표준 set_new_handler
, 그러나 자동 쓰레기 수집을 목적으로 하는 물체 도달 가능성에 대한 정의는 제공하지 않았습니다. C++11은 포인터 값이 다른 값에서 "안전하게 도출되는" 조건을 정의합니다. 구현은 엄격한 포인터 안전 하에서 동작하도록 지정할 수 있으며, 이 경우 이러한 규칙에 따라 유도되지 않은 포인터는 무효가 될 수 있습니다.
특성
C++11은 언어에 대한 컴파일러/도구 확장을 위한 표준 구문을 제공합니다. 이러한 확장은 전통적으로 다음을 사용하여 지정되었습니다. #pragma
지시 또는 공급업체별 키워드(예: __attribute__
GNU 및 __declspec
Microsoft)의 경우. 새로운 구문을 사용하면 추가된 정보를 이중 대괄호로 둘러싸인 속성의 형태로 지정할 수 있습니다. 속성은 소스 코드의 다양한 요소에 적용할 수 있습니다.
인트의 [[attr1]] i [[attr2, attr3]]; [[attr4(arg1, arg2)]] 한다면 (조건부의) { [[노점상::attr5]] 돌아가다 i; }
위 예제에서 속성 attr1
변수 유형에 적용됩니다. i
, attr2
그리고. attr3
변수 자체에 적용합니다. attr4
에 적용되는 if
성명서와 vendor::attr5
반환 명세서에 적용됩니다. 일반적으로(그러나 일부 예외를 제외하고) 명명된 엔티티에 대해 지정된 속성은 이름 뒤에 배치되며, 그렇지 않은 경우 엔티티 앞에는 위와 같이 여러 속성이 이중 대괄호 한 쌍의 내부에 나열될 수 있으며 속성에 대해 추가된 인수가 제공될 수 있습니다. 및 속성은 벤더 고유 속성 이름 공간으로 범위를 지정할 수 있습니다.
속성은 언어적 의미가 없으며 무시 시 프로그램의 감각을 변경하지 않는 것이 좋습니다. 속성은 예를 들어 컴파일러가 더 나은 진단을 발행하거나 생성된 코드를 최적화하는 데 도움이 되는 정보를 제공하는 데 유용할 수 있습니다.
C++11은 다음과 같은 두 가지 표준 속성을 제공합니다. noreturn
함수가 반환되지 않도록 지정하고, carries_dependency
함수 인수 또는 반환 값이 종속성을 가지고 있음을 나타내어 다중 threaded 코드를 최적화하는 데 도움이 됩니다.
C++ 표준 라이브러리 변경 사항
C++11 표준 라이브러리에는 여러 가지 새로운 기능이 도입되었습니다. 이 중 많은 부분이 기존 표준에서 구현되었을 수 있지만, 일부는 새로운 C++11 핵심 기능에 의존합니다.
새로운 도서관의 상당 부분은 2005년 발간된 C++ 표준 위원회의 도서관 기술 보고서(TR1이라고 함)에서 정의되었습니다. 현재 네임스페이스를 사용하여 TR1의 다양한 전체 및 부분 구현을 사용할 수 있습니다. std::tr1
. C++11의 경우 네임스페이스로 이동되었습니다. std
. 그러나 TR1 기능이 C++11 표준 라이브러리에 도입됨에 따라 초기 TR1 버전에서는 사용할 수 없었던 C++11 언어 기능으로 적절한 경우 업그레이드되었습니다. 또한 C++03에서는 가능했지만 원래 TR1 사양에는 포함되지 않은 기능으로 향상되었을 수 있습니다.
표준 라이브러리 구성 요소로 업그레이드
C++11은 기존의 표준 라이브러리 구성 요소가 누릴 수 있는 여러 가지 새로운 언어 기능을 제공합니다. 예를 들어, 대부분의 표준 라이브러리 컨테이너는 Rvalue 참조 기반 이동 컨스트럭터 지원의 혜택을 받을 수 있습니다. 무거운 컨테이너를 빠르게 이동할 수도 있고 컨테이너의 내용물을 새 메모리 위치로 이동할 수도 있습니다. 표준 라이브러리 구성 요소는 적절한 경우 새로운 C++11 언어 기능으로 업그레이드되었습니다. 여기에는 다음이 포함되지만 반드시 이에 국한되는 것은 아닙니다.
- R값 참조 및 관련 이동 지원
- UTF-16 인코딩 유닛 및 UTF-32 인코딩 유닛 유니코드 문자 유형 지원
- Variadic 템플릿(완벽한 전달을 위해 Rvalue 참조와 결합)
- 컴파일 타임 상수 식
decltype
explicit
변환 연산자- 기본값으로 선언된 기능 또는 삭제된 기능
또한 이전 C++ 표준 이후 많은 시간이 흘렀습니다. 표준 라이브러리를 사용하는 많은 코드가 작성되었습니다. 이것은 약간의 개선을 사용할 수 있는 표준 라이브러리의 일부를 드러냈습니다. 고려된 많은 개선 분야 중에는 표준 도서관 할당자가 포함되어 있습니다. 이전 모델을 보완하기 위해 C++11에 할당자의 새로운 범위 기반 모델이 포함되었습니다.
스레딩 설비
C++03 언어는 쓰레딩을 지원하는 메모리 모델을 제공하지만, 쓰레딩을 실제로 사용하기 위한 기본 지원은 C++11 표준 라이브러리와 함께 제공됩니다.
스레드 클래스()std::thread
)가 제공되며, 이는 새 스레드에서 실행할 함수 개체(및 이 개체에 전달할 수 있는 선택적인 일련의 인수)를 가져옵니다. 다른 실행 스레드가 완료될 때까지 스레드를 중지시켜 다음을 통해 스레드 결합을 지원할 수 있습니다. std::thread::join()
멤버 기능. 가능한 경우 플랫폼별 작업을 위해 기본 네이티브 스레드 개체에 대한 액세스가 제공됩니다. std::thread::native_handle()
멤버 기능.
스레드 간의 동기화를 위해 적절한 음소거(mutex)std::mutex
, std::recursive_mutex
, 등) 및 조건 변수()std::condition_variable
그리고. std::condition_variable_any
)가 라이브러리에 추가됩니다. RAI(Resource Acquisition Is Initialization) 잠금을 통해 액세스할 수 있습니다.std::lock_guard
그리고. std::unique_lock
) 및 잠금 알고리즘을 쉽게 사용할 수 있습니다.
고성능의 낮은 수준의 작업을 위해서는 뮤트크세스의 오버헤드 없이 스레드 간의 통신이 필요한 경우가 있습니다. 이것은 메모리 위치에서 원자 연산을 사용하여 수행됩니다. 작업에 필요한 최소 메모리 가시성 제약 조건을 선택적으로 지정할 수 있습니다. 이러한 목적을 위해 명시적인 메모리 장벽을 사용할 수도 있습니다.
C++11 스레드 라이브러리는 또한 스레드 간에 비동기적인 결과를 전달하기 위한 선물과 약속을 포함합니다. std::packaged_task
비동기적인 결과를 생성할 수 있는 함수 호출을 마무리합니다. 선물 제안은 선물을 결합하고 약속의 집합 안에서 하나의 약속의 완료를 확인할 방법이 부족하다는 비판을 받았습니다.[24]
스레드 풀과 같은 더 높은 수준의 스레드화 시설은 향후 C++ 기술 보고서로 재송부되었습니다. 이들은 C++11의 일부는 아니지만, 궁극적인 구현은 스레드 라이브러리 기능 위에 완전히 구축될 것으로 예상됩니다.
더 뉴 std::async
facility는 작업을 실행하고 작업을 연결하는 편리한 방법을 제공합니다. std::future
. 사용자는 작업을 별도의 스레드에서 비동기식으로 실행할지 또는 값을 기다리는 스레드에서 동기식으로 실행할지 선택할 수 있습니다. 기본적으로 구현은 선택할 수 있으며, 이는 초과 구독 없이 하드웨어 동시성을 쉽게 활용할 수 있는 방법을 제공하며, 간단한 사용을 위한 스레드 풀의 장점 중 일부를 제공합니다.
튜플형
튜플은 미리 배열된 차원의 이질적인 개체로 구성된 집합입니다. 튜플은 구조물의 구성원 변수의 일반화로 간주될 수 있습니다.
TR1 튜플 타입의 C++11 버전은 버라이어티 템플릿과 같은 C++11 기능의 혜택을 받았습니다. 합리적인 구현을 위해 TR1 버전은 구현 정의된 최대 포함 유형 수와 상당한 매크로 트릭을 필요로 했습니다. 반면 C++11 버전의 구현에는 명시적인 구현 정의된 최대 유형 수가 필요하지 않습니다. 컴파일러는 템플릿 인스턴스화를 위한 내부 최대 재귀 깊이를 갖지만(정상), C++11 버전의 튜플은 이 값을 사용자에게 노출시키지 않습니다.
다양한 템플릿을 사용하여 튜플 클래스의 선언은 다음과 같습니다.
템플릿 <학급 ...종류들> 학급 투플;
튜플 유형의 정의 및 사용 예:
타이프디프 std::투플 <인트의, 두 배의, 긴 &, 상투적인 촤 *> 테스트_ tup; 긴 장황한 = 12; 테스트_ tup 증명의 (18, 6.5, 장황한, "차오!"); 장황한 = std::얻다<0>(증명의); // 값 18을 'lengthy'에 할당합니다. std::얻다<3>(증명의) = " 아름답습니다!; // 튜플의 네 번째 요소를 수정합니다.
튜플을 만드는 것이 가능합니다. proof
내용을 정의하지 않고 튜플 요소의 유형에 기본 생성자가 있는 경우에만 해당합니다. 또한 다른 튜플에 튜플을 할당할 수도 있습니다. 두 튜플의 유형이 동일한 경우 각 요소 유형에 복사 생성자가 있어야 합니다. 그렇지 않은 경우, 오른쪽 튜플의 각 요소 유형은 왼쪽 튜플의 해당 요소 유형의 요소 유형으로 변환 가능해야 하거나 왼쪽 튜플의 해당 요소 유형이 적합한 생성자를 가지고 있어야 합니다.
타이프디프 std::투플 <인트의 , 두 배의, 끈의 > 투플_1 t1; 타이프디프 std::투플 <촤, 짧다 , 상투적인 촤 * > 투플_2 t2 ('X', 2, "홀라!"); t1 = t2; // 좋아요, 먼저 두 요소를 변환할 수 있습니다. // 세 번째는 'const char *'로 구성할 수 있습니다.
같은 std::make_pair
위해서 std::pair
, 존재합니다. std::make_tuple
자동으로 만들어 내다 std::tuple
유형 공제를 사용하고 auto
그런 투플을 선언하는 데 도움이 됩니다. std::tie
lvalue 참조의 튜플을 생성하여 튜플을 풀도록 도와줍니다. std::ignore
여기에도 도움이 됩니다. 예를 참조하십시오.
오토 기록. = std::make_ tup(하리람, 뉴델리, 3.5, 가.); std::끈의 이름. ; 흘러가다 gpa ; 촤 등급. ; std::넥타이(이름., std::아랑곳하지 않는, gpa, 등급.) = 기록. ; // std:: ignore는 지명 삭제를 도와줍니다. std::꾸트 << 이름. << ' ' << gpa << ' ' << 등급. << std::끝을 맺다 ;
관계 연산자는 (같은 수의 요소를 가진 튜플 사이에서) 사용할 수 있으며, 튜플의 특성을 확인하기 위해 두 가지 표현식을 사용할 수 있습니다(컴플리케이션 중에만).
std::tuple_size<T>::value
튜플의 요소 수를 반환합니다.T
,std::tuple_element<I, T>::type
개체 번호의 유형을 반환합니다.I
투플의T
.
해시 테이블
C++ 표준 라이브러리에 해시 테이블(주문되지 않은 연관 컨테이너)을 포함하는 것은 가장 반복적인 요청 중 하나입니다. C++03에서는 시간 제약으로만 채택되지 않았습니다. 해시 테이블은 최악의 경우 균형 잡힌 트리보다 효율성이 떨어지지만(많은 충돌이 있는 경우) 많은 실제 응용 프로그램에서 더 나은 성능을 발휘합니다.
충돌은 위원회가 (무엇보다 요소 삭제가 인정되는 경우) 상당히 많은 본질적인 문제를 도입하는 오픈 어드레싱의 솔루션을 표준화하는 것이 적절하다고 생각하지 않았기 때문에 선형 연결을 통해서만 관리됩니다. 자체 해시 테이블 구현을 개발한 비표준 라이브러리와의 이름 충돌을 피하기 위해 "해시" 대신 "순서 없는" 접두사를 사용했습니다.
새 라이브러리에는 동일한 키(고유 키 또는 동등한 키)를 가진 요소를 받아들일지 여부와 각 키를 연관된 값으로 매핑할지 여부에 따라 구별되는 네 가지 유형의 해시 테이블이 있습니다. 이들은 기존의 4개의 이진 검색 트리 기반 연관 컨테이너에 해당하며, 다음을 포함합니다. 순서 없는 접두사.
해시 테이블의 종류 | 연관값 | 등가 키 |
---|---|---|
std::unordered_set | 아니요. | 아니요. |
std::unordered_multiset | 아니요. | 네. |
std::unordered_map | 네. | 아니요. |
std::unordered_multimap | 네. | 네. |
새 클래스는 컨테이너 클래스의 모든 요구 사항을 충족하며 요소에 액세스하는 데 필요한 모든 방법을 갖추고 있습니다. insert
, erase
, begin
, end
.
이 새로운 기능은 C++ 언어 코어 확장이 필요하지 않았습니다(구현은 다양한 C++11 언어 기능을 활용하지만), 헤더의 작은 확장만 필요했습니다. <functional>
그리고 헤더의 도입. <unordered_set>
그리고. <unordered_map>
. 기존 표준 클래스에 대한 다른 변경 사항은 필요하지 않았으며 표준 라이브러리의 다른 확장에 의존하지 않습니다.
정규식
새 헤더에 정의된 새 라이브러리 <regex>
, 는 몇 가지 새로운 클래스로 구성되어 있습니다.
- 정규식은 템플릿 클래스의 인스턴스별로 표시됩니다.
std::regex
; - 발생은 템플릿 클래스의 인스턴스로 표시됩니다.
std::match_results
, - std::regex_iterator는 regex의 모든 일치에 대해 반복하는 데 사용됩니다.
함수. std::regex_search
는 검색에 사용되고, 함수를 '검색 및 교체'하는 데 사용됩니다. std::regex_replace
새 문자열을 반환하는 데 사용됩니다.[25]
다음은 의 사용 예입니다. std::regex_iterator
:
# <regex> 상투적인 촤 *양식 = R"([^,.\t\n]+)"; // 공백, 쉼표, 마침표 탭 새 줄로 구분된 단어 찾기 std::regex rgx(양식); // 잘못된 패턴에 예외를 적용합니다. 상투적인 촤 *과녁의 = 언시스턴트 대학교-앙크 모르포크; // regex_iterator를 사용하여 '패턴' 문자로 구분된 '대상' 단어를 모두 식별합니다. 오토 반복적인 = std::cregex_iterator(과녁의, 과녁의 + 힘줄이 있는(과녁의), rgx); // 순서 반복을 끝내다 오토 끝. = std::cregex_iterator(); 위해서 (; 반복적인 != 끝.; ++반복적인) { std::끈의 match_str = 반복적인->스트레이트(); std::꾸트 << match_str << '\n''; }
도서관 <regex>
(적절한 경우에는 사용하지만) 기존 헤더의 변경이나 핵심 언어의 확장을 필요로 하지 않습니다. POSIX C에서는 C POSIX 라이브러리 #regex.h를 통해 정규 표현식을 사용할 수도 있습니다.
범용 스마트 포인터
C++11 제공 std::unique_ptr
, 에 대한 개선 사항. std::shared_ptr
그리고. std::weak_ptr
TR1부터. std::auto_ptr
값이 떨어집니다.
확장 가능 난수 시설
C 표준 라이브러리는 함수를 통해 의사 난수를 생성하는 기능을 제공합니다. rand
. 그러나 알고리즘은 전적으로 라이브러리 공급업체에 위임되어 있습니다. C++는 이 기능을 그대로 물려받았지만, C++11은 의사 난수를 생성하는 새로운 방법을 제공합니다.
C++11의 난수 기능은 난수 생성기의 상태를 포함하고 의사난수를 생성하는 생성기 엔진과 결과의 범위와 수학적 분포를 결정하는 분포로 구분됩니다. 이 두 가지를 결합하여 난수 생성 개체를 형성합니다.
C 표준과 달리 rand
, C++11 메커니즘은 세 가지 기본 발전기 엔진 알고리즘과 함께 제공됩니다.
C++11은 또한 다음과 같은 여러 표준 분포를 제공합니다.
uniform_int_distribution
,uniform_real_distribution
,bernoulli_distribution
,binomial_distribution
,geometric_distribution
,negative_binomial_distribution
,poisson_distribution
,exponential_distribution
,gamma_distribution
,weibull_distribution
,extreme_value_distribution
,normal_distribution
,lognormal_distribution
,chi_squared_distribution
,cauchy_distribution
,fisher_f_distribution
,student_t_distribution
,discrete_distribution
,piecewise_constant_distribution
그리고.piecewise_linear_distribution
.
생성기와 분포는 다음 예제와 같이 결합됩니다.
# <random> # <기능적> std::균일_int_ distrib 분포<인트의> 분배(0, 99); std::mt19937 엔진의; // 메르센 트위스터 MT19937 오토 발전기 = std::결박시키다(분배, 엔진의); 인트의 무작위의 = 발전기(); // 0과 99 사이의 균일한 적분 변수를 생성합니다. 인트의 랜덤2 = 분배(엔진의); // 분포 및 엔진 개체를 사용하여 직접 다른 샘플을 생성합니다.
포장지참조
클래스 템플릿의 인스턴스에서 래퍼 참조를 가져옵니다. reference_wrapper
. 래퍼 참조는 일반 참조(')와 유사합니다.&
C++ 언어의 '). 객체에서 래퍼 참조를 얻으려면 함수 템플릿 ref
는 (일정한 참조를 위해) 사용됩니다. cref
사용됨).
래퍼 참조는 복사가 아닌 매개변수 참조가 필요한 함수 템플릿에 대해 무엇보다 유용합니다.
// 이 함수는 매개 변수 'r'을 참조하여 증분합니다. 공허한 재미있는 (인트의 &r) { r++; } // 템플릿 함수. 템플릿<학급 F, 학급 P> 공허한 g (F f, P t) { f(t); } 인트의 주된() { 인트의 i = 0; g (재미있는, i); // 'g< void(int &r), int>'가 인스턴스화됩니다. // 그러면 'i'는 수정되지 않습니다. std::꾸트 << i << std::끝을 맺다; // 출력 -> 0 g (재미있는, std::심판을 보다(i)); // g< void(int &r),reference_wrapper<int>'가 인스턴스화됩니다. // 그러면 'i'가 수정됩니다. std::꾸트 << i << std::끝을 맺다; // 출력 -> 1 }
이 새로운 유틸리티가 기존에 추가되었습니다. <functional>
머리글과 C++ 언어의 확장이 필요하지 않았습니다.
함수 개체의 다형성 래퍼
함수 객체에 대한 다형성 래퍼는 의미론 및 구문에서 함수 포인터와 유사하지만 덜 엄격하게 바인딩되어 래퍼의 인수와 호환되는 인수(함수 포인터, 멤버 함수 포인터 또는 펑터)라고 할 수 있는 모든 것을 무차별적으로 참조할 수 있습니다.
예를 들어 다음과 같은 특성을 명확히 할 수 있습니다.
std::기능.<인트의 (인트의, 인트의)> 재미있는; // 다음을 사용하여 래퍼 만들기 // 템플릿 클래스 'function'입니다. std::더해서<인트의> 더하다; // 'plus'는 'template< class T > T plus ( T, T )'로 선언됩니다. // 그러면 'add'는 'int add(intx, inty)'를 입력합니다. 재미있는 = 더하다; // 확인 - 매개변수 및 반환 유형이 동일합니다. 인트의 a = 재미있는 (1, 2); // 참고: 포장지 'func'가 어떤 기능을 가리키는 것이 아니라면, // 예외 'std::bad_function_call'이(가) 포함됩니다. std::기능.<흥얼거리다 (짧다, 짧다)> func2 ; 한다면 (!func2) { // func2'에 아직 함수가 할당되지 않았기 때문에 true입니다. 흥얼거리다 인접한(긴 x, 긴 y); func2 = &인접한; // 확인 - 매개 변수 및 반환 유형은 변환 가능합니다. 짜임새 있는 시험 { 흥얼거리다 교환입니다.()(짧다 x, 짧다 y); }; 시험 차; 재미있는 = std::심판을 보다(차); // 'std::ref'는 래퍼를 반환하는 템플릿 함수입니다. // 구조물 '자동차'의 멤버 기능 'operator()'에 해당합니다. } 재미있는 = func2; // 확인 - 매개 변수 및 반환 유형은 변환 가능합니다.
템플릿 클래스 function
헤더 안에 정의되었습니다. <functional>
, C++ 언어를 변경할 필요가 없습니다.
메타프로그래밍을 위한 유형 특성
메타프로그래밍은 다른 프로그램(또는 그 자체)을 만들거나 수정하는 프로그램을 만드는 것으로 구성됩니다. 이는 컴파일 중 또는 실행 중에 발생할 수 있습니다. C++ 표준 위원회는 템플릿을 통한 컴파일 시 메타 프로그래밍을 위한 라이브러리를 도입하기로 결정했습니다.
다음은 C++03 표준을 사용하는 메타 프로그램의 예입니다. 정수 지수를 계산하기 위한 템플릿 인스턴스의 재귀입니다.
템플릿<인트의 B, 인트의 N> 짜임새 있는 포우 { // 재귀적 호출 및 재조합. 열거한{ 가치 = B*포우<B, N-1>::가치 }; }; 템플릿< 인트의 B > 짜임새 있는 포우<B, 0> { // ''N == 0'' 종료 조건입니다. 열거한{ 가치 = 1 }; }; 인트의 사분의 일 = 포우<3, 4>::가치;
C++의 템플릿은 일반적인 프로그래밍을 지원하고 코드를 더 컴팩트하고 유용하게 만들기 때문에 많은 알고리즘이 다양한 유형의 데이터에서 작동할 수 있습니다. 그럼에도 불구하고 알고리즘은 사용되는 데이터 유형에 대한 정보가 필요한 경우가 일반적입니다. 이 정보는 유형 특성을 사용하여 템플릿 클래스를 인스턴스화하는 동안 추출할 수 있습니다.
유형 특성은 개체의 범주와 클래스(또는 구조)의 모든 특성을 식별할 수 있습니다. 새 헤더에 정의되어 있습니다. <type_traits>
.
다음 예제에는 주어진 데이터 유형에 따라 제안된 두 알고리즘 중 하나를 인스턴스화하는 템플릿 함수 '세공'이 있습니다.Algorithm::do_it
).
// 첫 번째 조작 방법. 템플릿< 흥얼거리다 B > 짜임새 있는 알고리즘. { 템플릿<학급 T1, 학급 T2> 정적인 인트의 하다_하다 (T1 &, T2 &) { /*...*/ } }; // 두 번째 조작 방법입니다. 템플릿<> 짜임새 있는 알고리즘.<진실의> { 템플릿<학급 T1, 학급 T2> 정적인 인트의 하다_하다 (T1, T2) { /*...*/ } }; // '세심하게' 인스턴스화하면 올바른 작동 방법이 자동으로 인스턴스화됩니다. 템플릿<학급 T1, 학급 T2> 인트의 치밀한 (T1 A, T2 B) { // 'T1'이 정수이고 'T2'가 정수인 경우에만 두 번째 방법을 사용합니다. // 부동 소수점의 경우, 그렇지 않으면 첫 번째 방법을 사용합니다. 돌아가다 알고리즘.<std::is_<T1>::가치 && std::is_floating_점<T2>::가치>::하다_하다( A, B ) ; }
헤더에 정의된 유형 특성을 통해 <type_traits>
, 유형 변환 작업을 생성하는 것도 가능합니다.static_cast
그리고. const_cast
템플릿 안에 부족합니다.
이런 종류의 프로그래밍은 우아하고 간결한 코드를 만들어내지만, 이러한 기술의 약점은 컴파일 중에는 불편하고 프로그램 실행 중에는 매우 어렵다는 디버깅입니다.
함수 객체의 반환 유형을 계산하기 위한 균일한 방법
특히 반환 값이 함수의 매개 변수에 따라 달라지는 경우 컴파일 시 템플릿 함수 개체의 반환 유형을 결정하는 것은 직관적이지 않습니다. 예를 들어 다음과 같습니다.
짜임새 있는 분명한 { 인트의 교환입니다.()(인트의) 상투적인; // 매개변수 유형은 두 배의 교환입니다.()(두 배의) 상투적인; // 반환형과 동일합니다. }; 템플릿 <학급 오브제> 학급 미적분학. { 일반의: 템플릿<학급 아르그> 아르그 교환입니다.()(아르그& a) 상투적인 { 돌아가다 구성원(a); } 사적인: 오브제 구성원; };
클래스 템플릿 인스턴스화 Calculus<Clear>
, 의 목적 calculus
의 함수 개체와 항상 동일한 반환 유형을 가질 것입니다. Clear
. 단, 주어진 수업 Confused
아래:
짜임새 있는 혼란스러운 { 두 배의 교환입니다.()(인트의) 상투적인; // 매개 변수 유형이 아닙니다. 인트의 교환입니다.()(두 배의) 상투적인; // 반환형과 동일합니다. };
인스턴스화 시도 중 Calculus<Confused>
반환 유형을 유발할 것입니다. Calculus
학급의 그것과 같지 않은 Confused
. 컴파일러가 변환에 대한 경고를 생성할 수 있습니다. int
로. double
그리고 역도 성립.
TR1은 템플릿 클래스를 도입하고 C++11은 채택합니다. std::result_of
이를 통해 모든 선언에 대한 함수 개체의 반환 유형을 결정하고 사용할 수 있습니다. 물건이. CalculusVer2
을 사용합니다. std::result_of
함수 개체의 반환 유형을 도출하는 개체:
템플릿< 학급 오브제 > 학급 미적분학 Ver2 { 일반의: 템플릿<학급 아르그> 활자명 std::…의 결과<오브제(아르그)>::유형 교환입니다.()(아르그& a) 상투적인 { 돌아가다 구성원(a); } 사적인: 오브제 구성원; };
이러한 방식으로 기능 객체의 경우 CalculusVer2<Confused>
변환, 경고 또는 오류가 없습니다.
TR1 버전의 유일한 변경 사항 std::result_of
TR1 버전은 구현이 함수 호출의 결과 유형을 결정할 수 없도록 허용했습니다. 지원을 위한 C++ 변경으로 인해 decltype
, 의 C++11 버전 std::result_of
이러한 특수한 경우는 더 이상 필요하지 않습니다. 모든 경우에 유형을 계산하려면 구현이 필요합니다.
향상된 C 호환성
C와의 호환성을 위해 C99부터는 다음과 같이 추가되었습니다.[26]
- 전처리기:[27]
- 가변 매크로,
- 인접한 좁은/넓은 스트링 리터럴의 연결,
_Pragma()
– 와 동등한#pragma
.
long long
– 최소 64비트 길이의 정수 유형입니다.__func__
– 매크로 평가는 해당 함수의 이름에 맞게 수행됩니다.- 머리글:
cstdbool
(stdbool.h
),cstdint
(stdint.h
),cinttypes
(inttypes.h
).
원래 계획되었지만 제거되었거나 포함되지 않은 기능
별도의 TR로 향하는 중:
- 모듈
- 십진법
- 수학특수함수
연기됨:
- 컨셉트
- 보다 완벽하거나 필요한 쓰레기 수거 지원
- 반사
- 매크로 스코프
제거되거나 사용되지 않는 기능
하나의 작업이 다른 작업보다 먼저 시퀀싱되거나 두 작업이 시퀀싱되지 않도록 지정하는 것으로 대체되어 sequence point라는 용어가 제거되었습니다.[28]
키워드의 이전 사용 export
제거되었습니다.[29] 키워드 자체는 미래에 사용될 수 있도록 예약되어 남아 있습니다.
동적 예외 사양은 권장되지 않습니다.[29] 예외가 아닌 함수의 컴파일 시간 사양은 다음과 같이 사용할 수 있습니다. noexcept
최적화에 유용한 키워드입니다.
std::auto_ptr
다음으로 대체되어 사용되지 않습니다. std::unique_ptr
.
함수 개체 기본 클래스()std::unary_function
, std::binary_function
), 함수에 대한 포인터에 대한 어댑터 및 멤버에 대한 포인터에 대한 어댑터 및 바인더 클래스는 모두 사용되지 않습니다.
참고 항목
참고문헌
- ^ "We have an international standard: C++0x is unanimously approved". 12 August 2011. Archived from the original on 11 December 2018. Retrieved 12 August 2011.
- ^ Stroustrup, Bjarne. "C++11 FAQ". stroustrup.com. Archived from the original on 2018-10-06. Retrieved 2014-10-15.
- ^ "C++11 Overview: What specific design goals guided the committee?". Standard C++. Archived from the original on 2019-01-31. Retrieved 2015-09-04.
- ^ "Bjarne Stroustrup: A C++0x overview" (PDF). Archived (PDF) from the original on 17 June 2016. Retrieved 30 June 2011.
- ^ "ISO/IEC 14882:2011". ISO. 2 September 2011. Archived from the original on 29 January 2013. Retrieved 3 September 2011.
- ^ "Working Draft, Standard for Programming Language C++" (PDF). Archived (PDF) from the original on 2019-01-21. Retrieved 2012-04-26.
- ^ "The Standard". Archived from the original on 2019-05-13. Retrieved 2012-11-02.
- ^ "Clang - C++ Programming Language Status". web.archive.org. 2023-11-29. Retrieved 2023-12-01.
- ^ "GCC 4.8.1 released, C++11 feature complete : Standard C++". isocpp.org. Retrieved 2023-12-01.
- ^ 서터, 알렉산드레스쿠 "C++ 코딩 표준" #15
- ^ Gabriel Dos Reis; Bjarne Stroustrup (22 March 2010). "General Constant Expressions for System Programming Languages, Proceedings SAC '10" (PDF). Archived (PDF) from the original on 13 June 2018. Retrieved 18 August 2012.
- ^ Jaakko Järvi; Bjarne Stroustrup; Douglas Gregor; Jeremy Siek (April 28, 2003). "Decltype and auto, Programming Language C++, Document no: N1478=03-0061" (PDF). Archived (PDF) from the original on May 28, 2015. Retrieved June 6, 2015.
- ^ Roger Orr (June 2013). ""Auto – A Necessary Evil?" Overload Journal #115". Archived from the original on 2015-06-06. Retrieved 2015-06-06.
- ^ "Document no: N1968=06-0038- Lambda expressions and closures for C++" (PDF). Open Standards. Archived (PDF) from the original on 2011-07-28. Retrieved 2009-04-20.
- ^ "Decltype (revision 5)" (PDF). Archived (PDF) from the original on 2022-02-14. Retrieved 2022-02-16.
- ^ "auto specifier (since C++11) - cppreference.com". en.cppreference.com. Archived from the original on 2016-10-20. Retrieved 2016-10-18.
- ^ Gustedt, Jens (2019-07-09). "Introduce the nullptr constant - v1" (PDF). ISO JTC1/SC22/WG14 Document Register. International Organization for Standardization. Archived (PDF) from the original on 2020-07-27. Retrieved 2020-04-19 – via open-std.org.
- ^ 이로 인해 정수 리터럴과 같은 숫자 리터럴에서 숫자 그룹화를 위한 밑줄의 사용(다른 언어에서 일반적)과 충돌이 발생하여 C++14는 대신 아포스트로피(상단 쉼표로)를 그룹화에 사용합니다.Daveed Vandevoorde (2012-09-21). "N3448: Painless Digit Separation" (PDF). Archived (PDF) from the original on 2015-08-11. Retrieved 2015-08-13.
- ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): 프로그래밍 언어 – C++ §3.2 하나의 정의 규칙 [basic.def.odr] para. 3
- ^ a b "Defaulted and Deleted Functions – ISO/IEC JTC1 SC22 WG21 N2210 = 07-0070 – 2007-03-11". Archived from the original on 2012-08-19. Retrieved 2012-12-20.
- ^ "Using the GNU Compiler Collection (GCC): Long Long". gcc.gnu.org. Archived from the original on 2016-08-21. Retrieved 2016-07-25.
- ^ "Data Type Ranges (C++)". Archived from the original on 2009-02-21. Retrieved 2009-04-23.
- ^ 새뮤얼 피. Harbison III, Guy L. Steel Jr.: "C – A Reference Manual", 5판, p.251
- ^ Milewski, Bartosz (3 March 2009). "Broken promises–C++0x futures". Archived from the original on 16 September 2011. Retrieved 24 January 2010.
- ^ "C++ Regular expressions library". cppreference.com. Retrieved 10 December 2022.
- ^ "Clang - C++98, C++11, and C++14 Status". Clang.llvm.org. 2013-05-12. Archived from the original on 2019-05-28. Retrieved 2013-06-10.
- ^ "Working draft changes for C99 preprocessor synchronization". www.open-std.org. Archived from the original on 2020-07-31. Retrieved 2014-05-26.
- ^ Caves, Jonathan (4 June 2007). "Update on the C++-0x Language Standard". Archived from the original on 9 September 2011. Retrieved 25 May 2010.
- ^ a b Sutter, Herb (3 March 2010). "Trip Report: March 2010 ISO C++ Standards Meeting". Archived from the original on 11 July 2018. Retrieved 24 March 2010.
외부 링크
- C++ 표준 위원회
- C++0X: 표준 C++의 새로운 얼굴
- Herb Sutter 블로그 C++11 취재
- Anthony Williams의 C++11 블로그 취재
- 워털루 대학의 Bjarne Stroustrup이 Wayback Machine에서 한 C++0x 강연
- 언어의 상태: Bjarne Stroustrup과의 인터뷰 (2008년 8월 15일) 2009년 1월 31일 웨이백 머신에 보관된
- 컴파일러에서 C++0x 핵심 언어 기능과 해당 기능의 가용성을 추적하는 데 도움이 되는 위키 페이지
- 온라인 C++11 표준 라이브러리 참조
- 온라인 C++11 컴파일러
- Bjarne Stroustrup의 C++11 FAQ
- C++11 기능에 대한 자세한 내용: 루프에 대한 범위 기반, auto_ptr이 사용되지 않는 이유 등.