로그인하고 있지 않습니다. 편집하면 당신의 IP 주소가 공개적으로 기록됩니다. 계정을 만들고 로그인하면 편집 시 사용자 이름만 보이며, 위키 이용에 여러 가지 편의가 주어집니다.스팸 방지 검사입니다. 이것을 입력하지 마세요!=== C++11 === [[2010년]] 이전에 나올 것으로 예상되어 초기 개발명이 C++0x이었지만 때를 한참 넘겨 [[2011년]]에 공개되었다. C++11에서는 다른 프로그래밍 언어에서 사용되던 편리한 문법과 개념이 많이 추가되었다 ==== 문법의 변화 ==== C++11 최종 표준 사양 문서인 Programming Languages - C++ N3290 참고. <br /> * 유니코드에 대한 지원이 강화되었다. :UTF-8, UTF-16, UTF-32지원을 위한 자료형이 추가되었으며, 변환에 필요한 라이브러리가 추가되었다. 다만 비주얼스튜디오의 경우, 2015버전부터 지원한다. <syntaxhighlight lang="cpp"> char16_t a = u'리'; // ISO 10646 문자집합 중 단일 16비트 유닛을 취급. 최소 2바이트. 부호 없음. char32_t b = U'브'; // ISO 10646 문자집합을 취급. 최소 4바이트. 부호 없음. wchar_t c = L'레'; // 1바이트로 표현 못하는 문자 취급. 크기는 미정의. auto ucs4_ga = '\uAC00'; // 16진수로 UCS-4 문자값 표기 (0x0000AC00) 한글 '가'. auto ucs4_poo = '\U0001F4A9' // 16진수로 UCS-4 문자값 표기 (0x0001F4A9) 똥 그림. </syntaxhighlight> <br /> * overide키워드가 추가되었다 :overide 키워드는 자식 클래스가 부모 클래스의 멤버 함수를 재정의할 때, 재정의해야 할 부모클래스의 멤버함수가 없을 경우, 컴파일 단계에서 에러를 뿜어준다. <syntaxhighlight lang="cpp"> struct A { virtual int func(char x); }; struct B : A { int func(int x) override; // 오류! 이 함수는 가상함수를 오버라이드 하지 못했음. int func(char x) override; // ok }; </syntaxhighlight> <br /> * final 키워드가 추가되었다. :더 이상 상속을 못하게 하거나, 오버라이드를 금지하는 키워드이다. 아래는 상속 금지. <syntaxhighlight lang="cpp"> struct AAA final // 상속 금지. { ...생략... }; struct BBB : AAA // 오류! { ...생략... }; </syntaxhighlight> :아래는 오버라이드 금지. <syntaxhighlight lang="cpp"> struct A { virtual int func(char x) final; // 오버라이드 금지. }; struct B : A { int func(int x); // ok int func(char x); // 오류! }; </syntaxhighlight> <br /> * 기존의 auto 예약어의 기능이 없어지고 변수 선언시 초기화 값에 따라 변수형을 추론할 수 있게 됐다. <syntaxhighlight lang="cpp"> auto var = 1; //이 경우 var의 변수형은 int형이 된다. auto var2 = new Person(); //이 경우 var2의 변수형은 (Person*)이 된다. </syntaxhighlight> <br /> * 정적 배열의 경우 for문에서 자바의 for문과 같은 범위기반 for문(range-based for loop)을 사용할 수 있다. :사용자 컨테이너의 경우 차례대로 순환할 수 있는 iterator 인터페이스를 컴파일러에게 제공할 수 있다면 마찬가지로 이 새로운 for문을 사용할 수 있다. 표준 라이브러리에서 제공하는 컨테이너들은(vector, list 등) 대부분 그런 인터페이스가 이미 있기 때문에 그냥 사용하면 된다. <syntaxhighlight lang="cpp"> int a[] = {1,2,3,4,5}; for(auto & it : a) { std::cout<<it<<endl; } </syntaxhighlight> <br /> * 표현식(expression)의 타입추론을 돕는 decltype 키워드가 추가되었다. <syntaxhighlight lang="cpp"> decltype(1/1.0) a; // double a; decltype(a) b; // double b; decltype(main()) c; // int c; decltype(&c) d; // int* d; decltype((c)) e = c; // int& e = c; decltype(std::move(c)) f = 22; // int&& f = 22; </syntaxhighlight> :이 키워드는 템플릿 메타 프로그래밍에서 요긴하게 쓰인다. <syntaxhighlight lang="cpp"> template <typename T, typename F> auto execute(const T& value, F func) -> decltype(func(value)) { return func(value); } </syntaxhighlight> <br /> * 공통 초기법(uniform initialization)이 도입되면서 초기화 방법이 통합되었다. <syntaxhighlight lang="cpp"> struct data { int A, B; char C; } data x {1, 3, 'F'}; data func() { return {2, 5, 'Z'}; } </syntaxhighlight> <br /> * 개체나 함수, 표현식을 컴파일 시점에 계산하도록 만드는 constexpr 키워드가 추가되었다. <syntaxhighlight lang="cpp"> constexpr int square( int x ) { return x * x; } const int a{ square(22) }; // ok int b{ square(a) }; // ok, 그러나 실행시점 계산. int c{ square(b) }; // 오류! b는 상수식이 아니라서 square의 x를 알아낼 수 없음. </syntaxhighlight> :constexpr 함수는 재귀도 가능하다. <syntaxhighlight lang="cpp"> constexpr double factorial( double x ) { return x == 0.0 ? 1.0 : x * factorial( x - 1.0 ); } // constexpr 함수의 재귀 깊이는 최소 약 512 중첩까지다. </syntaxhighlight> :클래스의 생성자를 constexpr로 만들 수 있다. 단, 이렇게 되면 그 클래스는 컴파일 시점에 계산할 수 있어야 한다. <syntaxhighlight lang="cpp"> class AAA { public: int x; constexpr AAA( int i ) : x{i} {} AAA() : x{22} {} }; const int a{ AAA{22}.x }; // constexpr const int b{ AAA{}.x }; // non-constexpr </syntaxhighlight> :const와 constexpr은 같은 개념이 절대 아니다. const는 <b>이것은 읽기 전용이다.</b>를 의미하고 constexpr은 <b>이것은 컴파일 시점에 계산된다.</b>를 의미한다. 아래는 const와 constexpr의 차이를 코드로 나타낸 것이다. <syntaxhighlight lang="cpp"> int func( int x ) { const int a{x}; ... } int func( int x ) { constexpr int a{x}; // 오류! ... } </syntaxhighlight> <br /> * Parameter Pack이 추가되어 가변 인자 템플릿을 구현할 수 있게 되었다. <syntaxhighlight lang="cpp"> template<typename... Types> void f(Types... args); </syntaxhighlight> <br /> * 최적화된 예외처리 기능을 제공하는 noexcept 키워드가 추가되었다. :try 구간이 시작되면 예외 처리기 및 스택 되감기 코드가 삽입되며 이러한 것들은 굉장히 무거운 기능이다. 그러나 어떤 예외가 터질지, 그 예외가 바깥으로 삐져나올지 말지, 만약 바깥으로 삐져나오면 어느 단에서 처리될 것인지의 여부를 컴파일러가 예측할 방법이 없으므로 관련된 코드마다 컴파일러는 이런 무거운 기능을 죄다 삽입한다. <syntaxhighlight lang="cpp"> void func_except() { try { throw 22; } catch( int ee ) { ee = 0xEE; } } // 비록 이 함수가 자체적으로 예외를 처리하더라도 컴파일러는 그걸 모른다. // 그래서 이 함수를 사용하는 다른 함수들도 스택 되감기를 위한 코드를 가지게 된다. void a() { func_except(); } // 이놈 때문에... void b() { a(); } // 스택 되감기 준비. void c() { b(); } // 스택 되감기 준비. void d() { c(); } // 스택 되감기 준비. ... void z() { y(); } // 스택 되감기 준비. int main() { z(); } </syntaxhighlight> :이러한 오버헤드를 줄이기 위해 컴파일러에게 예외 힌트를 제공하는 <s>컴파일러 개발자를 토하게 만드는</s>throw() 문법이 있었지만 C++11부터 deprecated가 됐다. 그 대안으로 추가된 것이 noexcept 키워드다. noexcept가 지정된 함수는 예외가 일어나지 않거나, 예외가 일어나더라도 그 함수 내부에서 해결됨을 보장한다는 뜻이다. 즉, 컴파일 중 noexcept 함수를 만난 컴파일러는 그 함수가 사용되는 모든 코드마다 스택 되감기를 삽입하는 짓을 하지 않는다. 위의 코드에서 a() 함수를 a() noexcept로 만들면 b(), c(), d(), ... z() 함수까지의 스택 되감기 코드가 사라진다.<ref>참고로, 이렇게 사용자를 믿은<s>오빠를 믿은</s> 컴파일러를 배신하고 noexcept 함수 바깥으로 예외를 던져버리면, 윗단에 그 예외를 받을 수 있는 코드가 있더라도 다 쌩까고 std::terminate()를 호출하여 프로그램을 그 자리에서 박살낸다...</ref> <br /> * nullptr 키워드가 추가되어 0과 구분되는 NULL을 공식으로 지원하게 되었다. <syntaxhighlight lang="cpp"> int* a = NULL; // ok int b = NULL; // ok int* c = nullptr; // ok int d = nullptr; // 오류! void f(int); void f(int*); f(NULL); // <- void f(int) 호출 f(nullptr); // <- void f(int* x) 호출. </syntaxhighlight> <br /> * 사용자 정의 리터럴이 추가되었고, 그 operator를 정의할 수 있게 되었다. <syntaxhighlight lang="cpp"> using u64 = unsigned long long; constexpr int operator "" _k ( u64 x ) { return int{ x * 1024 }; } const auto sum = 32_k + 128_k ; // const int sum = 32768 + 131072; </syntaxhighlight> <br /> * using 키워드에 type alias 기능이 추가되었다. <syntaxhighlight lang="cpp"> typedef unique_ptr<unordered_map<int, std::string>> uum; //typedef using uum = unique_ptr<unordered_map<int, std::string>>; //using typedef void(*Func)(int, const std::string&); // typedef using Func = void(*)(int, const std::string&); // using </syntaxhighlight> <br /> * using 키워드를 사용하여 alias template을 정식으로 지원하게 되었다. <syntaxhighlight lang="cpp"> //typedef template<typename T1, typename T2> struct uptr { typedef unique_ptr<unordered_map<T1, T2>> uum; }; //using (alias template) template<typename T1, typename T2> using uum = unique_ptr<unordered_map<T1, T2>>; </syntaxhighlight> <br /> * 우측값과 이동 생성자, 이동 대입 연산자가 추가되었다. :auto_ptr의 논리적 결함을 해결하기 위해 추가된 개념이다. 이 개념 덕분에 자료를 복사해야 하는지 옮겨야 하는지 예측이 가능하게 되어 여러 방면에서 극적인 성능 향상을 꾀할 수 있게 됐다.<s>하지만 C++ 초보자들은 그저 멘붕<sup>멘붕</sup>.</s> <br /> * 람다식및 익명함수가 추가되었다. <syntaxhighlight lang="cpp"> auto f = [](int x, int y) { return x + y; }; auto result = f( 1, 2 ); // result = 3; [](){}(); // void 무명() { return; }을 호출한 것. </syntaxhighlight> <br /> * POD<ref>plain old data, memset이나 memcpy등을 사용할 수 있는 객체</ref>의 정의가 수정되었다. <syntaxhighlight lang="cpp"> struct A {}; // POD struct B { B(){} }; // standard-layout struct C { virtual ~C(){} }; // 그 무엇도 아님. struct D { int x; private: int y; }; // trivial struct E { int x; int y; }; // POD struct F { void foo(){} }; // POD (C++11 이전에는 성립 안됨.) </syntaxhighlight> <br /> * std::initializer_list가 추가되어 POD가 아니어도 리스트 형식으로 초기화가 가능해졌다. * extern 템플릿을 사용하여 템플릿 컴파일 시간을 크게 줄일 수 있게 됐다. * 대리 생성자(delegating constructor)가 추가됐다. <syntaxhighlight lang="cpp"> class Rect { public: Rect() : Rect(22) {} Rect(int d) : Rect(0, 0, d) {} Rect(int x, int y) : Rect(x, y, 22) {} Rect(int x, int y, int d) : Rect(x, y, x+d, y+d) {} Rect(int x, int y, int w, int h) : top(x), left(y), right(w), bottom(h) {} ... }; </syntaxhighlight> <br /> * delete 함수와 default 함수가 추가됐다. <syntaxhighlight lang="cpp"> class NonCopyable { public: int a; NonCopyable() {} NonCopyable( int x ) : a(x) {} NonCopyable& operator= ( const NonCopyable& src ) = delete; }; NonCopyable A(22), B; B = A; // 오류! 복사 대입 연산자는 사용 금지된 함수입니다! </syntaxhighlight> :default 함수는 기본 생성자, 복사 생성자, 복사 대입 연산자, 이동 생성자, 이동 대입 연산자, 파괴자에게만 지정할 수 있다. 그냥 말 그대로 내용 없는 기본 함수를 컴파일러가 만들어준다. <syntaxhighlight lang="cpp"> class NonDefaultCtor { public: int a; NonDefaultCtor( int x ) : a(x) {} }; NonDefaultCtor A1( 4 ); // ok NonDefaultCtor A2; // 오류! 기본 생성자가 없음. class DefaultCtor { public: int b; DefaultCtor() = default; DefaultCtor( int x ) : b(x) {} }; DefaultCtor B1( 4 ); // ok DefaultCtor B2; // ok </syntaxhighlight> <br /> * 새로운 함수의 표현식이 추가됐다. <syntaxhighlight lang="cpp"> auto NewStyle( int x ) -> int; // int NewStyle( int x ); </syntaxhighlight> <br /> * namespace의 버전 관리(versioning)를 쉽게 해주는 기능이 추가됐다. <syntaxhighlight lang="cpp"> namespace Julia { inline namespace V20 { int Age(void) { return 20; } } namespace V15 { int Age(void) { return 15; } } } int a = Julia::V20::Age(); // a는 20 int b = Julia::V15::Age(); // b는 15 int c = Julia::Age(); // c는 20 </syntaxhighlight> <br /> * 강타입 열거형(strong typed enums)이 추가됐다. <syntaxhighlight lang="cpp"> // 아래는 강타입 열거형 enum class Weekday { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; // 아래는 전통 열거형 enum Colors { RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET }; Colors c = RED; // ok Weekday w = Sunday; // 오류! Weekday::Sunday 로 해야됨. int a = INDIGO; // ok int b = Weekday::Saturday; // 오류! 열거형은 int형이 아닙니다. // 아래는 Weekday가 사용하는 기호 상수와 중복되는 이름이 있음. 그래도 ok. // 사용할 때 TimeTable::Monday 처럼 사용하면 됨. enum class TimeTable { Monday, Tuesday, Wednesday, Thursday, Friday }; // 아래는 Colors가 사용하는 기호 상수와 중복되므로 오류! enum TrafficLight { RED, GREEN }; </syntaxhighlight> <br /> * 정적 assertion이 추가됐다. 컴파일 타임에 assertion을 발동시킨다. <syntaxhighlight lang="cpp"> // 예시 1: static_assert( sizeof(void*) == 8, "The target machine needs LP64 or LLP64." ); // 예시 2: template< class T, size_t N > class SomethingAwesomeClass { static_assert( N > 0, "N must be greater than zero." ); ... }; SomethingAwesomeClass<int,22> A; // ok SomethingAwesomeClass<int,0> B; // 컴파일 중단됨! </syntaxhighlight> ==== 표준 라이브러리의 변화 ==== * std::thread가 추가되었고 멀티 스레딩을 지원하는 메모리 모델로 수정되었다. 또한 동기화 지원을 위한 std::mutex가 추가되었다. * 레퍼런스 카운터를 이용한 메모리 클래스인 std::shared_ptr와 std::weak_ptr, 그리고 독점소유 클래스인 std::unique_ptr이 추가되었다. 또한 std::auto_ptr은 비추천으로 바뀌었다. * 기존의 함수포인터를 대체하는 std::function 클래스가 추가되었다. 이번에 추가된 람다식이 이 클래스와 궁합이 잘 맞는다. * 시간에 관한 클래스 라이브러리 std::chrono가 추가되었다. 무단 변경 가능성 있는 실제 시간(wall time)을 다룰 때는 std::chrono::system_clock 클래스를, 변경되지 않고 꾸준히 흐르는 시간(monotonic)을 다룰 때는 std::chrono::steady_clock 클래스를, 가장 정밀한 틱 간격을 얻으려면 std::chrono::high_resolution_clock<ref>플랫폼에 따라서는 system_clock이나 steady_clock이 high_resolution_clock 역할을 대신 하는 경우도 있다. 윈도우즈 환경에서는 high_resolution_clock을 steady_clock이 대신 하고 있다.</ref>을 사용하면 된다. * 난수에 관한 클래스 라이브러리 <random>이 추가되었다.<s>하지만 쓰다보면 짜증나서 걍 rand 돌린다...</s><ref>각각 독립적인 주사위를 굴려야 하는 상황이라면 당연히 rand 사용은 지양해야 할 것이다.</ref> 크게 엔진과 어댑터로 구성된 발생기(generator)와 그것을 쪼개는 분배기(distribution)로 나뉘어 있다. 난수 전문가가 아니면 도저히 알아먹기 힘든 다양한 발생기와 균등 분포, 베르누이 분포, 푸아송 분포, 정규 분포, 표본 분포로 구분짓는 20여개의 분배기를 제공한다. 난수 하나를 얻기 위해서 엔진을 결정하고 시드를 결정하고 분배기를 결정한 다음, 분배기에 엔진을 물리고, 분배기를 돌려야 한다. 난수 전문가가 아니라면 일반적인 여건에서 정수형 균등 분배기에 메르센 트위스터 엔진을 연결하면 무난하다. * 정적 배열 클래스 std::array가 추가됐다. 말 그대로 선언하는 즉시 굳어버리는 고정 배열이며, C++에서 언어적으로 지원해주는 배열을 포장한 것이다.<ref>iterator를 지원하고 배열을 다룰 때 발생하는 몇몇 실수를 사전 예방 해준다는 차이점이 있다.</ref> 초기화 할 때 주어지는 요소들을 통해 배열 크기를 컴파일러가 알아서 잡아주지 못한다는 <s>존나 심각한</s>단점이 있다. * <algorithm> 라이브러리가 대폭 강화됐다. std::all_of, std::any_of, std::none_of 등등 자주 쓰일 법한 많은 것들이 추가됐다. * 간편하게 사용하는 이종간 데이터들의 묶음인 std::tuple이 추가됐다.<ref>비주얼스튜디오 2010의 경우 가변인자 템플릿 기능이 구현되지 않아서 라이브러리 개발자<s>STL씨일듯?</s>가 직접 재귀 템플릿 꼼수를 사용하여 std::tuple을 구현했다. 그래서 한 번에 받을 수 있는 데이터 종류의 수가 정해져 있다. 그 이후의 비주얼스튜디오는 어떻게 됐는지 다른 위키러가 추가바람.</ref> * 템플릿 변태질의 정점에 다다를 수 있는 <type_traits> 연장이 추가됐다. 진정 템플릿 덕후라면 이 라이브러리를 잘 활용하자. 실제로는 데이터 타입을 이래저래 조작하거나 식별할 수 있는 도구다. 모든 건 컴파일 타임에 이루어진다. * 비정렬 컨테이너인 std::unordered_map과 std::unordered_set이 추가됐다. 정렬하지 않기 때문에 당연히 기존의 std::map과 std::set보다 빠르다.<s>타이핑이 귀찮은게 심각한 단점.</s> * 단방향 리스트인 std::forward_list가 추가됐다. 얘는 그냥 앞만 보고 달리는 리스트다. 자기가 데이터를 몇 개 달고 있는지 모르니까 사용시 주의. * 정규 표현식을 다루는 std::regex가 추가됐다. 일부 C++ 개발자들에게는 혁명이라고 표현되는 개선점 중 하나. ===== 그 외 ===== * 가비지 컬렉션에 대한 내용이 표준에 추가되었다, 하지만 어떠한 컴파일러도 구현하지 않았다. * 원래 C++11에 템플릿의 새로운 개념인 <s>템플릿 변태질의 끝판왕인</s>컨셉(Concepts)이 들어갈 예정이었다. 그러나 시간이 촉박하여 해당 개념의 추가는 차후로 밀려나고 말았다. 요약: 리브레 위키에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 3.0 라이선스로 배포됩니다(자세한 내용에 대해서는 리브레 위키:저작권 문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요. 글이 직접 작성되었거나 호환되는 라이선스인지 확인해주세요. 리그베다 위키, 나무위키, 오리위키, 구스위키, 디시위키 및 CCL 미적용 사이트 등에서 글을 가져오실 때는 본인이 문서의 유일한 기여자여야 하고, 만약 본인이 문서의 유일한 기여자라는 증거가 없다면 그 문서는 불시에 삭제될 수 있습니다. 취소 편집 도움말 (새 창에서 열림) | () [] [[]] {{}} {{{}}} · <!-- --> · [[분류:]] · [[파일:]] · [[미디어:]] · #넘겨주기 [[]] · {{ㅊ|}} · <onlyinclude></onlyinclude> · <includeonly></includeonly> · <noinclude></noinclude> · <br /> · <ref></ref> · {{각주}} · {|class="wikitable" · |- · rowspan=""| · colspan=""| · |} {{lang|}} · {{llang||}} · {{인용문|}} · {{인용문2|}} · {{유튜브|}} · {{다음팟|}} · {{니코|}} · {{토막글}} {{삭제|}} · {{특정판삭제|}}(이유를 적지 않을 경우 기각될 가능성이 높습니다. 반드시 이유를 적어주세요.) {{#expr:}} · {{#if:}} · {{#ifeq:}} · {{#iferror:}} · {{#ifexist:}} · {{#switch:}} · {{#time:}} · {{#timel:}} · {{#titleparts:}} __NOTOC__ · __FORCETOC__ · __TOC__ · {{PAGENAME}} · {{SITENAME}} · {{localurl:}} · {{fullurl:}} · {{ns:}} –(대시) ‘’(작은따옴표) “”(큰따옴표) ·(가운뎃점) …(말줄임표) ‽(물음느낌표) 〈〉(홑화살괄호) 《》(겹화살괄호) ± − × ÷ ≈ ≠ ∓ ≤ ≥ ∞ ¬ ¹ ² ³ ⁿ ¼ ½ ¾ § € £ ₩ ¥ ¢ † ‡ • ← → ↔ ‰ °C µ(마이크로) Å °(도) ′(분) ″(초) Α α Β β Γ γ Δ δ Ε ε Ζ ζ Η η Θ θ Ι ι Κ κ Λ λ Μ μ(뮤) Ν ν Ξ ξ Ο ο Π π Ρ ρ Σ σ ς Τ τ Υ υ Φ φ Χ χ Ψ ψ Ω ω · Ά ά Έ έ Ή ή Ί ί Ό ό Ύ ύ Ώ ώ · Ϊ ϊ Ϋ ϋ · ΐ ΰ Æ æ Đ(D with stroke) đ Ð(eth) ð ı Ł ł Ø ø Œ œ ß Þ þ · Á á Ć ć É é Í í Ĺ ĺ Ḿ ḿ Ń ń Ó ó Ŕ ŕ Ś ś Ú ú Ý ý Ź ź · À à È è Ì ì Ǹ ǹ Ò ò Ù ù · İ Ż ż ·  â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û · Ä ä Ë ë Ï ï Ö ö Ü ü Ÿ ÿ · ǘ ǜ ǚ ǖ · caron/háček: Ǎ ǎ Č č Ď ď Ě ě Ǐ ǐ Ľ ľ Ň ň Ǒ ǒ Ř ř Š š Ť ť Ǔ ǔ Ž ž · breve: Ă ă Ğ ğ Ŏ ŏ Ŭ ŭ · Ā ā Ē ē Ī ī Ō ō Ū ū · à ã Ñ ñ Õ õ · Å å Ů ů · Ą ą Ę ę · Ç ç Ş ş Ţ ţ · Ő ő Ű ű · Ș ș Ț ț