C++ 주해서 버전 10.9.0

Frank B. Brokken

Center of Information Technology,
University of Groningen
Nettelbosje 1,
P.O. Box 11044,
9700 CA Groningen
The Netherlands
Published at the University of Groningen
ISBN 90 367 0470 7

1994 - 2017

이 문서는 C 언어를 (또는 기타 C-류의 문법을 사용하는 Perl이나 Java 같은 언어를) 잘 알고 있는 사용자가 C++ 를 더 잘 알고 싶고 또 이주하고 싶은 사용자들을 위한 책이다. 이 문서는 프랭크(Frank) 교수의 C++ 프로그래밍 강좌의 교재로 사용되고 있다. 이 강좌는 매년 그로닝겐(Groningen) 대학에 개설된다. 그렇지만 C++ 주해서는 C++ 언어의 모든 면모를 다루지는 않는다. 특히 C++의 기본 문법이 C의 문법과 같은 경우는 다루지 않는다. C 기본서라면 어느 것이든 참고해 C++의 문법에 적용해도 무방하다.

종이에 인쇄될 버전으로 C++ 주해서를 얻으려면 zip-파일에서 포스트스크립트(postscript) 형식 그리고 pdf와 기타 형식을 다음에서 얻을 수 있다.

https://github.com/fbb-git/cppannotations-zip

안에 이름이 cplusplus로 시작하는 파일은 A4 용지 규격이고 이름이 cplusplusus로 시작하는 파일은 US legal 용지 규격이다. C++ 주해서는 킨들 전자책으로도 얻을 수 있다.

최신 버전의 C++ 주해서를 html-형식으로 얻으려면 다음을 열람해 보라:

https://fbb-git.github.io/cppannotations/
또는 다음을 열람하시면 된다.
http://www.icce.rug.nl/documents/

주저하지 말고 되먹임을 주시기를 바란다. C++ 주해서가 마음에 들면 이-메일을 보내주시기를 바란다. 중요한 내용이 빠졌다고 생각되거나 텍스트나 예제에서 철자 오류를 발견했다면 또는 그저 메일을 보내고 싶다면 Frank B. Brokken으로 메일을 보내면 된다.

모쪼록 참조중인 문서 버전을 언급해 주기를 바란다. 제목에서 보실 수 있다 (이 문서는 10.9.0이다). 그리고 참조 중인 장과 문단 이름 또는 번호를 언급해 주시면 된다.

접수한 모든 메일은 성심껏 처리한다. 개선 제안을 받아들여 C++ 주해서를 새로 갱신할 때 반영한다. 단, 개선 제안을 받아들이지 않기로 결정하는 경우는 예외이다. 이 때문에 여러분의 노고를 폄하한다고 오해하지 마시기를 바란다.

목차

제 1 장: 개관

제 2 장: 들어가는 말

2.1: C++ 주해서의 성장사

2.2: C++의 역사

2.2.1: C++ 주해서의 탄생
2.2.2: C++ 컴파일러로 C 프로그램을 컴파일하는 법
2.2.3: C++ 프로그램을 컴파일하는 법
2.2.3.1: MS-윈도우즈에서의 C++
2.2.3.2: C++ 소스 컴파일하기
2.2.3.3: C++14

2.3: C++ 장점과 주장

2.4: 객체-지향 프로그래밍이란 무엇인가?

2.5: C와 C++ 사이의 차이점

2.5.1: `main' 함수
2.5.2: 줄끝 주석
2.5.3: 엄격한 유형 점검
2.5.4: 함수 중복정의
2.5.5: 기본 함수 인자
2.5.6: NULL-포인터와 0-포인터 그리고 nullptr
2.5.7: `void' 매개변수 리스트
2.5.8: `#define __cplusplus'
2.5.9: 표준 C 함수 사용하기
2.5.10: C와 C++에 공동 헤더 파일
2.5.11: 지역 변수 정의하기
2.5.12: `typedef' 키워드
2.5.13: 구조체 안의 함수
2.5.14: C++17 표준에 도입된 특징들

제 3 장: C++ 첫 만남

3.1: C와의 눈에 띄는 차이점

3.1.1: `const' 키워드 사용하기
3.1.2: 이름공간(Namespaces)
3.1.3: 영역 지정 연산자 ::
3.1.4: `cout'과 `cin' 그리고 `cerr'

3.2: 구조체 안의 함수

3.2.1: 데이터 감추기: public과 private 그리고 class
3.2.2: C의 구조체와 C++의 구조체

3.3: C의 문법에 추가된 C++의 문법

3.3.1: 참조
3.3.2: Rvalue 참조
3.3.2.1: Rvalue 심화 연구
3.3.3: 강력하게 유형이 정의되는 열거체
3.3.4: 초기화 리스트
3.3.5: `auto'를 사용하여 유형 추론하기
3.3.5.1: 구조화된 묶기 선언 (C++17)
3.3.6: 유형 정의와 'using' 선언
3.3.7: 범위-기반의 for-회돌이
3.3.8: 날 문자열 기호상수
3.3.9: 이진 상수
3.3.10: 속성
3.3.11: (C++17) 초기화자가 있는 선택 서술문

3.4: 새로 정의된 데이터 유형

3.4.1: `bool' 데이터 유형
3.4.2: `wchar_t' 데이터 유형
3.4.3: 유니코드 인코딩
3.4.4: `long long int' 데이터 유형
3.4.5: `size_t' 데이터 유형
3.4.6: C++14: 자릿수 구분자

3.5: 새로운 유형변환 구문

3.5.1: `static_cast'-연산자
3.5.2: `const_cast'-연산자
3.5.3: `reinterpret_cast'-연산자
3.5.4: `dynamic_cast'-연산자
3.5.5: 'shared_ptr' 객체의 유형변환

3.6: C++ 키워드와 예약된 이름

제 4 장: 이름공간

4.1: 이름공간(Namespaces)

4.1.1: 이름공간 정의하기
4.1.1.1: 이름공간에 개체 선언하기
4.1.1.2: 닫힌 이름공간
4.1.2: 개체 참조하기
4.1.2.1: `using' 지시어
4.1.2.2: `쾨닉 찾기'
4.1.3: 표준 이름공간
4.1.3.1: std::placeholders 이름공간
4.1.4: 이름공간 내포와 이름공간의 별칭
4.1.4.1: 이름공간 밖에 개체 정의하기

제 5 장: `string' 데이터 유형

5.1: 문자열 연산

5.2: std::string 참조

5.2.1: 초기화
5.2.2: 반복자
5.2.3: 연산자
5.2.4: 멤버 함수
5.2.5: 변환 함수

제 6 장: IO-스트림 라이브러리

6.1: 특별한 헤더 파일

6.2: `ios_base' 바탕 클래스

6.3: `streambuf' 객체 인터페이스: `ios' 클래스

6.3.1: 조건 상태
6.3.2: 입력과 출력의 형식화
6.3.2.1: 형식을 변경하는 멤버 함수
6.3.2.2: 형식화 깃발

6.4: 출력

6.4.1: 기본 출력: `ostream' 클래스
6.4.1.1: `ostream' 객체에 쓰기
6.4.1.2: `ostream' 위치 찾기
6.4.1.3: `ostream' 비우기
6.4.2: 파일에 출력하기: `ofstream' 클래스
6.4.2.1: 스트림 객체 열기 모드
6.4.3: 메모리에 출력하기: `ostringstream' 클래스

6.5: 입력

6.5.1: 기본 입력: `istream' 클래스
6.5.1.1: `istream' 객체로부터 읽기
6.5.1.2: `istream' 위치 지정
6.5.2: 파일로부터 입력: `ifstream' 클래스
6.5.3: 메모리로부터 입력: `istringstream' 클래스
6.5.4: 스트림 복사하기
6.5.5: 스트림 연결짓기

6.6: 고급 주제

6.6.1: 스트림 이동하기
6.6.2: 스트림 방향전환하기
6.6.3: 스트림을 읽고 쓰기

제 7 장: 클래스

7.1: 생성자

7.1.1: 첫 어플리케이션
7.1.2: 생성자: 인자의 유무
7.1.2.1: 생성 순서

7.2: 모호성 해결

7.2.1: `Data' 유형과 `Data()'
7.2.2: 과도하게 많은 괄호
7.2.3: 기존의 유형

7.3: 객체 안의 객체: 합성

7.3.1: 합성과 상수 객체: 상수 멤버 초기화자
7.3.2: 합성과 참조 객체: 참조 멤버 초기화자

7.4: 데이터 멤버 초기화자

7.4.1: 생성자 위임

7.5: 활괄호(통일) 초기화

7.6: default 키워드와 delete 키워드

7.7: 상수 멤버 함수와 상수 객체

7.7.1: 익명 객체
7.7.1.1: 익명 객체의 미묘함

7.8: `inline' 키워드

7.8.1: 멤버를 인라인으로 정의하기
7.8.2: 인라인 함수를 사용해야 할 때
7.8.2.1: 인라인 함수를 사용하면 안될 때
7.8.3: 인라인 변수(C++17)

7.9: 지역 클래스: 함수 안의 클래스

7.10: `mutable' 키워드

7.11: 헤더 파일의 조직

7.11.1: 헤더 파일에 이름공간 사용하기

7.12: 클래스 데이터 멤버에 적용된 Sizeof

제 8 장: 정적 데이터와 함수

8.1: 정적 데이터

8.1.1: 비공개 정적 데이터
8.1.2: 공개 정적 데이터
8.1.3: 정적 상수 데이터 초기화 하기
8.1.4: 일반화된 상수 표현식 (constexpr)
8.1.4.1: 상수 표현식 데이터

8.2: 정적 멤버 함수

8.2.1: 호출 관례

제 9 장: 클래스와 메모리 할당

9.1: `new' 연산자와 `delete' 연산자

9.1.1: 배열 할당
9.1.2: 배열 삭제
9.1.3: 배열 확장
9.1.4: `날' 메모리 관리
9.1.5: `배치 new' 연산자

9.2: 소멸자

9.2.1: 객체 포인터 심화 연구
9.2.2: set_new_handler() 함수

9.3: 할당 연산자

9.3.1: 할당 연산자 중복정의하기
9.3.1.1: 'operator=()' 멤버

9.4: `this' 포인터

9.4.1: 연속 할당과 this

9.5: 복사 생성자: 초기화와 할당

9.6: 할당 연산자의 설계 (제 I부)

9.6.1: 바꾸기
9.6.1.1: 빠르게 바꾸기

9.7: 데이터 이동

9.7.1: 이동 생성자 (동적 데이터)
9.7.2: 이동 생성자 (합성)
9.7.3: 이동-할당
9.7.4: 할당 연산자 고안하기 (제 II부)
9.7.5: 이동과 소멸자
9.7.6: 이동-전용 클래스
9.7.7: 기본 이동 생성자와 할당 연산자
9.7.8: 이동: 복잡한 클래스 디자인

9.8: 복사 생략과 반환 값 최적화

9.9: 평범한 구형 데이터

9.10: 결론

제 10 장: 예외

10.1: 예외 구문

10.2: 예외를 사용하는 예제

10.2.1: 구시대의 유물: `setjmp'와 `longjmp'
10.2.2: 예외: 좋은 대안

10.3: 예외 던지기

10.3.1: 빈 `throw' 서술문

10.4: try 블록

10.5: 예외 잡기

10.5.1: 기본 나포자

10.6: 예외 투수 선언하기 (비추천)

10.7: Iostream과 예외

10.8: 표준 예외

10.8.1: 사용할 것인가 말 것인가

10.9: 시스템 에러

10.9.1: std::error_code 클래스
10.9.2: std::error_category 클래스
10.9.3: std::error_condition 클래스
10.9.4: system_error 클래스

10.10: 예외 보장

10.10.1: 기본 보장
10.10.2: 강력 보장
10.10.3: 절대 보장

10.11: 함수 try 블록

10.12: 생성자와 소멸자에서의 예외

제 11 장: 연산자 중복정의 심화 연구

11.1: `operator[]()' 중복정의 하기

11.2: 삽입과 추출 연산자 중복정의 하기

11.3: 변환 연산자

11.4: `explicit' 키워드

11.4.1: 명시적인 변환 연산자

11.5: 증감 연산자 중복정의

11.6: 이항 연산자 중복정의

11.6.1: 멤버 함수 참조 바인딩 (& 그리고 &&)

11.f: 이항 연산자 중복정의(C++17)

11.f.a: 멤버 함수 참조 바인딩 (& 그리고 &&)

11.7: `operator new(size_t)' 중복정의

11.8: `operator delete(void *)' 중복정의

11.9: `new[]' 연산자와 `delete[]' 연산자

11.9.1: `new[]' 중복정의
11.9.2: `delete[]' 중복정의
11.9.3: C++14: `operator delete(void *, size_t)' 가족
11.9.4: `new[]'와 `delete[]' 그리고 예외

11.10: 함수 객체

11.10.1: 조작자 생성하기
11.10.1.1: 인자를 요구하는 조작자

11.11: [io]fstream::open() 사례 연구

11.12: 사용자-정의 기호상수

11.13: 중복정의가 가능한 연산자

제 12 장: 추상 컨테이너

12.1: 이 장에 사용된 표기법

12.2: `pair' 컨테이너

12.3: 할당자

12.4: 컨테이너

12.4.1: array 컨테이너
12.4.2: vector 컨테이너
12.4.3: list 컨테이너
12.4.4: queue 컨테이너
12.4.5: priority_queue 컨테이너
12.4.6: deque 컨테이너
12.4.7: map 컨테이너
12.4.7.1: map 생성자
12.4.7.2: map 연산자
12.4.7.3: map 공개 멤버
12.4.7.4: map: 간단한 예제
12.4.8: multimap 컨테이너
12.4.9: set 컨테이너
12.4.10: multiset 컨테이너
12.4.11: stack 컨테이너
12.4.12: unordered_map 컨테이너 (`해시 테이블')
12.4.12.1: unordered_map 생성자
12.4.12.2: unordered_map 공개 멤버
12.4.12.3: unordered_multimap 컨테이너
12.4.13: unordered_set 컨테이너
12.4.13.1: unordered_multiset 컨테이너
12.4.14: C14: 이질적인 찾기

12.5: complex 컨테이너

12.6: 무제한 공용체

12.6.1: 소멸자 구현하기
12.6.2: 둘러싼 클래스에 무제한 공용체 내장하기
12.6.3: 내장된 무제한 공용체 파괴하기
12.6.4: 복사 생성자와 이동 생성자
12.6.5: 할당

Chapter 13: 상속

13.1: 관련 유형

13.1.1: 상속의 깊이: 어디까지 바람직한가?

13.2: 접근 권한: public, private, protected

13.2.1: 공개 상속과 보호 상속 그리고 비밀 상속
13.2.2: 접근 권한 승격

13.3: 파생 클래스 생성자

13.3.1: 이동 생성
13.3.2: 이동 할당
13.3.3: 상속 생성자

13.4: 파생 클래스 소멸자

13.5: 멤버 함수 재정의하기

13.6: 다중 상속

13.7: 바탕 클래스와 파생 클래스 사이의 변환

13.7.1: 객체 할당으로 변환
13.7.2: 포인터 할당으로 변환

13.8: new[]로 비-기본 생성자를 사용하기

제 14 장: 다형성

14.1: 가상 함수

14.2: 가상 소멸자

14.3: 순수 가상 함수

14.3.1: 순수 가상 함수 구현하기

14.4: 명시적인 가상 재정의

14.5: 가상 함수와 다중 상속

14.5.1: 다중 상속의 모호성
14.5.2: 가상 기본 클래스
14.5.3: 가상 파생이 적절하지 않을 때

14.6: 실행 시간 유형 식별

14.6.1: dynamic_cast 연산자
14.6.2: `typeid' 연산자

14.7: 상속: 언제 무엇을 위하여 사용할 것인가?

14.8: `streambuf' 클래스

14.8.1: 보호 `streambuf' 멤버
14.8.1.1: 입력 연산을 위한 보호 멤버
14.8.1.2: 출력 연산을 위한 보호 멤버
14.8.1.3: 버퍼 조작을 위한 보호 멤버
14.8.1.4: `streambuf'로부터 클래스 파생시키기
14.8.2: `filebuf' 클래스
14.8.3: 스트림을 안전하게 또다른 std::streambuf에 연결하기

14.9: 다형적 예외 클래스

14.9.a: `std::error_category' 클래스

14.10: 다형성을 구현하는 법

14.11: vtable에 대한 미정의 참조 ...

14.12: 가상 생성자

제 15장: 친구 클래스(Friends)

15.1: 친구 함수

15.2: 확장 친구 함수 선언

제 16 장: 멤버를 가리키는 포인터를 가진 클래스

16.1: 멤버를 가리키는 포인터: 예제

16.2: 멤버를 가리키는 포인터 정의하기

16.3: 멤버를 가리키는 포인터 사용하기

16.4: 정적 멤버를 가리키는 포인터

16.5: 포인터 크기

제 17 장: 내포 클래스

17.1: 내포 클래스 정의하기

17.2: 내포 클래스 선언하기

17.3: 내포 클래스 안의 사적 멤버에 접근하기

17.4: 열거체 내포하기

17.4.1: 빈 열거체

17.5: 가상 생성자 심화 연구

제 18 장: 표준 템플릿 라이브러리

18.1: 미리 정의되어 있는 함수 객체

18.1.1: 연산 함수 객체
18.1.2: 관계 함수 객체
18.1.3: 논리 함수 객체
18.1.4: 함수 적용자
18.1.4.1: `bind' 함수 템플릿
18.1.4.2: 부인자(Negators)

18.2: 반복자(Iterators)

18.2.1: std::distance
18.2.2: 삽입 반복자
18.2.3: `istream' 객체용 반복자
18.2.3.1: `istreambuf' 객체용 반복자
18.2.4: `ostream' 객체용 반복자
18.2.4.1: `ostreambuf' 객체용 반복자

18.3: 'unique_ptr' 클래스

18.3.1: `unique_ptr' 객체 정의하기
18.3.2: 단순한 `unique_ptr' 객체 만들기
18.3.3: 또다른 `unique_ptr' 이동하기
18.3.4: 새로 할당된 객체 가리키기
18.3.5: 연산자와 멤버 함수
18.3.6: 배열에 `unique_ptr' 객체 사용하기
18.3.7: 비추천된 'auto_ptr' 클래스

18.4: 'shared_ptr' 클래스

18.4.1: `shared_ptr' 객체 정의하기
18.4.2: 단순한 `shared_ptr' 만들기
18.4.3: 새로 할당된 객체 가리키기
18.4.4: 연산자와 멤버 함수
18.4.5: 공유 포인터 유형 변환하기(Casting)
18.4.6: 배열에 `shared_ptr' 객체 사용하기

18.5: 똑똑한 포인터 만들기

18.6: 포인터 데이터 멤버를 가진 클래스

18.7: 람다 표현식

18.7.1: 람다 표현식 구문
18.7.2: 람다 표현식 사용하기
18.7.3: C++14: 람다 표현식 확장

18.8: 정규 표현식

18.8.1: 정규 표현식 미니 언어
18.8.1.1: 문자 부류(classes)
18.8.2: 정규 표현식 정의하기: std::regex
18.8.3: 부합 열람하기: std::match_results
18.8.4: 정규 표현식 부합 함수
18.8.4.1: std::regex_constants::match_flag_type 플래그
18.8.4.2: 전체 텍스트에 부합: std::regex_match
18.8.4.3: 부분적으로 텍스트에 부합: std::regex_search
18.8.4.4: 멤버함수 std::match:_results::format
18.8.4.5: 목표 문자열 변경하기: std::regex_replace

18.9: 난수화 그리고 통계 분포

18.9.1: 난수 엔진
18.9.2: 통계 분포
18.9.2.1: 베르누이(Bernoulli) 분포
18.9.2.2: 이항(Binomial) 분포
18.9.2.3: 코시(Cauchy) 분포
18.9.2.4: 카이-제곱(Chi-squared) 분포
18.9.2.5: 극단 값(Extreme value) 분포
18.9.2.6: 지수(Exponential) 분포
18.9.2.7: 피셔 F(Fisher F) 분포
18.9.2.8: 감마(Gamma) 분포
18.9.2.9: 기하(Geometric) 분포
18.9.2.10: 로그-정규(Log-normal) 분포
18.9.2.11: 정규(Normal) 분포
18.9.2.12: 음의 이항(Negative binomial) 분포
18.9.2.13: 포아송(Poisson) 분포
18.9.2.14: 스튜던트 t(Student t) 분포
18.9.2.15: 균등 이산(Uniform int) 분포
18.9.2.16: 균등 연속(Uniform real) 분포
18.9.2.17: 베이불(Weibull) 분포

18.10: std::experimental/filesystem 이름공간

18.10.1: 파일 시스템 예외: filesystem_error
18.10.2: 파일 시스템 엔트리의 이름: 경로
18.10.3: 디렉토리 처리: directory_entry, (recursive_)directory_iterator
18.10.4: 디렉토리 엔트리 방문하기: (recursive_)directory_iterator
18.10.5: 파일 유형(file_type)과 파일 허가권(perms): file_status
18.10.6: 파일 시스템 공간에 관한 정보: space_info
18.10.7: 자유 함수

제 19 장: STL 총칭 알고리즘

19.1: 총칭 알고리즘

19.1.1: accumulate
19.1.2: adjacent_difference
19.1.3: adjacent_find
19.1.4: binary_search
19.1.5: copy
19.1.6: copy_backward
19.1.7: count
19.1.8: count_if
19.1.9: equal
19.1.10: equal_range
19.1.10.1: exchange
19.1.11: fill
19.1.12: fill_n
19.1.13: find
19.1.14: find_end
19.1.15: find_first_of
19.1.16: find_if
19.1.17: for_each
19.1.18: generate
19.1.19: generate_n
19.1.20: includes
19.1.21: inner_product
19.1.22: inplace_merge
19.1.23: iter_swap
19.1.24: lexicographical_compare
19.1.25: lower_bound
19.1.26: max
19.1.27: max_element
19.1.28: merge
19.1.29: min
19.1.30: min_element
19.1.31: mismatch
19.1.32: next_permutation
19.1.33: nth_element
19.1.34: partial_sort
19.1.35: partial_sort_copy
19.1.36: partial_sum
19.1.37: partition
19.1.38: prev_permutation
19.1.39: random_shuffle
19.1.40: remove
19.1.41: remove_copy
19.1.42: remove_copy_if
19.1.43: remove_if
19.1.44: replace
19.1.45: replace_copy
19.1.46: replace_copy_if
19.1.47: replace_if
19.1.48: reverse
19.1.49: reverse_copy
19.1.50: rotate
19.1.51: rotate_copy
19.1.52: search
19.1.53: search_n
19.1.54: set_difference
19.1.55: set_intersection
19.1.56: set_symmetric_difference
19.1.57: set_union
19.1.58: sort
19.1.59: stable_partition
19.1.60: stable_sort
19.1.61: swap
19.1.62: swap_ranges
19.1.63: transform
19.1.64: unique
19.1.65: unique_copy
19.1.66: upper_bound
19.1.67: 힙 알고리즘
19.1.67.1: `make_heap' 함수
19.1.67.2: `pop_heap' 함수
19.1.67.3: `push_heap' 함수
19.1.67.4: `sort_heap' 함수
19.1.67.5: 힙 함수를 사용하는 예제

19.2: STL: 함수 적용자에 관하여 더 자세히

19.2.1: 멤버 함수 적용자
19.2.2: 적용 가능한 (어댑터) 함수

제 20 장: 멀티 쓰레딩

20.1: 시간 다루기 (절대 시간과 상대 시간)

20.1.1: 단위: std::ratio 클래스
20.1.2: 시간의 양: std::chrono::duration
20.1.3: 시간을 측정하는 시계
20.1.4: 시점: std::chrono::time_point
20.1.5: 시간을 텍스트로 변환하기
20.1.5.1: std::put_time 형식 지정자

20.2: 멀티 쓰레딩

20.2.1: std::this_thread 이름공간
20.2.2: std::thread 클래스
20.2.2.1: 정적 데이터와 쓰레드: std::thread_local
20.2.2.2: 예외와 join()

20.3: 동기화 (상호배제(mutexes))

20.3.1: 멀티 쓰레드 프로그램의 초기화
20.3.2: 공유 상호배제(shared mutexes) C++14

20.4: 잠금과 잠금 처리

20.4.1: 데드락
20.4.2: 공유 잠금 C++14

20.5: 이벤트 처리 (조건 변수)

20.5.1: std::condition_variable 클래스
20.5.2: std::condition_variable_any 클래스
20.5.3: 조건 변수를 사용하는 예제

20.6: 상호배제가 불필요한 원자적 행위

20.7: 쓰레드를 활용한 퀵정렬 예제

20.8: 공유 상태

20.9: 비동기 반환 객체: std::future

20.9.1: std::future_error 예외와 std::future_errc 열거체

20.10: 공유 비동기 반환 객체: std::shared_future

20.11: 새 쓰레드 시작하기: std::async

20.12: 실행을 위한 준비 작업: std::packaged_task

20.13: `std::promise' 클래스

20.13.1: 예외 전파: std::exception_ptr

20.14: 예제: 멀티-쓰레드 컴파일

제 21 장: 함수 템플릿과 변수 템플릿

21.1: 함수 템플릿 정의하기

21.1.1: 템플릿 매개변수에 관한 고찰
21.1.2: Auto 그리고 decltype
21.1.3: 나중에-지정되는 반환 유형

21.2: 인자를 참조로 건네기 (참조 래퍼)

21.3: 지역 변수와 이름없는 유형을 템플릿 인자로 사용하기

21.4: 템플릿 매개변수 추론

21.4.1: Lvalue 변형
21.4.2: 자격 변형
21.4.3: 바탕 클래스로 변형
21.4.4: 템플릿 매개변수 추론 알고리즘
21.4.5: 템플릿 유형 축약

21.5: 함수 템플릿 선언하기

21.5.1: 구체화 선언

21.6: 함수 템플릿 구체화하기

21.6.1: `코드 비만' 없는 구체화

21.7: 명시적인 템플릿 유형 사용하기

21.8: 함수 템플릿 중복정의하기

21.8.1: 중복정의 함수 템플릿을 사용하는 예제
21.8.2: 함수 템플릿을 중복정의할 때 마주하는 모호성
21.8.3: 중복정의 함수 템플릿 선언하기

21.9: 유형을 우회하는 템플릿 특정화

21.9.1: 너무 많은 특정화를 피하기
21.9.2: 특정화 선언하기
21.9.3: 삽입 연산자를 사용할 때의 복잡성

21.10: 정적 표명

21.11: 숫치 제한

21.12: 함수 객체를 위한 다형적 포장자

21.13: 템플릿 정의 컴파일과 구체화

21.14: 함수 선택 매커니즘

21.14.1: 템플릿 유형 매개변수 결정하기

21.15: 교체 실패는 에러가 아니다

21.16: `if constexpr'을 이용한 조건적 함수 정의 (C++17)

21.17: 템플릿 선언 구문 요약

21.18: 가변 템플릿 (템플릿 변수) C++14

제 22 장: 클래스 템플릿

22.0.1: 템플릿 인자 추론 C++17

22.0.1.1: 간단한 정의
22.0.1.2: 명시적인 변환

22.1: 클래스 템플릿 정의하기

22.1.1: 순환 큐 구성하기: CirQue
22.1.2: 유형-없는 매개변수
22.1.3: 멤버 템플릿
22.1.4: CirQue의 생성자와 멤버함수
22.1.5: CirQue 객체 사용하기
22.1.6: 기본 클래스 템플릿 매개변수
22.1.7: 클래스 템플릿 선언하기
22.1.8: 템플릿 구체화 방지

22.2: 정적 데이터 멤버

22.2.1: `typename' 키워드의 확장 사용법

22.3: 유형을 우회하는 클래스 템플릿 특정화

22.3.1: 클래스 특정화의 예

22.4: 부분적 특정화

22.4.1: 쉬어가기: 간단한 행열 대수학의 개념
22.4.2: 행렬 클래스 템플릿
22.4.3: MatrixRow 부분적 특정화
22.4.4: MatrixColumn 부분적 특정화
22.4.5: 1x1 행렬: 모호성을 피하는 법

22.5: 가변 템플릿

22.5.1: 가변 템플릿의 정의와 사용
22.5.2: 완벽한 전달
22.5.3: 언팩 연산자
22.5.4: 비-유형 가변 템플릿
22.5.5: 뼈대 `not_fn' 부인자
22.5.6: 접기(Folding) 표현식

22.6: 터플(Tuples)

22.7: 함수 객체의 반환 유형 계산하기

22.8: 클래스 템플릿의 구체화

22.9: 클래스 템플릿과 구체화 처리하기

22.10: 친구(friends) 선언하기

22.10.1: 템플릿 안에 친구로 사용된 비-템플릿
22.10.2: 특정한 유형에 대하여 친구로 구체화된 템플릿
22.10.3: 친구로서의 언바운드 템플릿
22.10.4: 확장 친구 선언

22.11: 클래스 템플릿 파생

22.11.1: 클래스 템플릿으로부터 평범한 클래스 상속받기
22.11.2: 클래스 템플릿으로부터 템플릿 클래스 상속받기
22.11.3: 평범한 클래스로부터 클래스 템플릿 상속받기

22.12: 정적 다형성

22.12.1: 정적 다형성의 예
22.12.2: 동적 다형 클래스를 정적 다형 클래스로 변환하기
22.12.3: 정적 다형성을 이용하여 재구현을 피하는 법

22.13: 클래스 템플릿과 내포

22.14: 반복자 생성하기

22.14.1: `RandomAccessIterator' 구현
22.14.2: `reverse_iterator' 구현

제 23 장: 고급 템플릿 사용법

23.1: 알아야 할 세부 요소들

23.1.1: 클래스 템플릿 안에 내포된 유형을 돌려주기
23.1.2: 바탕 클래스 멤버를 위한 유형 결정 방법
23.1.3: ::template과 .template 그리고 ->template

23.2: 템플릿 메타 프로그래밍

23.2.1: 템플릿에 따라 달라지는 값
23.2.1.1: 정수 유형을 유형으로 변환하기
23.2.2: 템플릿을 사용하여 대안 선택하기
23.2.2.1: 중복정의 멤버 정의하기
23.2.2.2: 템플릿 매개변수가 함수인 클래스 구조
23.2.2.3: 예제
23.2.3: 템플릿: 재귀를 이용한 반복

23.3: 사용자-정의 기호상수

23.4: 템플릿 템플릿 매개변수

23.4.1: Policy classes - I
23.4.2: Policy classes - II: 템플릿인 템플릿 매개변수
23.4.2.1: Policy 클래스의 소멸자
23.4.3: 정책으로 구조 정의하기

23.5: 템플릿 별칭

23.6: 유형속성(Trait) 클래스

23.6.1: 클래스 유형인지 아닌지 구별하는 법
23.6.2: 유형 속성
23.6.3: std::error_code 파생 클래스
23.6.4: std::error_category 파생 클래스
23.6.5: std::error_condition 파생 클래스

23.7: `noexcept'로 강력 보장을 제공하기

23.8: 클래스 유형 변환에 대하여 더 자세히

23.8.1: 유형을 유형으로 변환하기
23.8.2: 빈 유형
23.8.3: 유형 변환의 가능성
23.8.3.1: 상속 결정

23.9: 템플릿 TypeList 처리하기

23.9.1: TypeList의 길이
23.9.2: TypeList 유형 검색하기
23.9.3: TypeList로부터 유형 선택하기
23.9.4: TypeList의 앞과 뒤에 유형 추가하기
23.9.5: TypeList로부터 유형 삭제하기
23.9.5.1: 첫 번째 나타난 유형을 삭제하기
23.9.5.2: 인덱스로 유형 삭제하기
23.9.5.3: 한 유형이 나타나면 모두 삭제하기
23.9.5.4: 중복 유형 삭제하기

23.10: TypeList 사용하기

23.10.1: Wrap과 Multi 클래스 템플릿
23.10.2: MultiBase 클래스 템플릿
23.10.3: Support 템플릿
23.10.4: Multi 클래스 사용하기

23.11: 표현식 템플릿

23.11.1: 표현식 템플릿 설계하기
23.11.2: 표현식 템플릿 구현하기
23.11.3: BasicType 유형정보 클래스와 클래스 순서

제 24 장: 실전 예제

24.1: `streambuf' 클래스에 파일 기술자 이용하기

24.1.1: 출력 연산용 클래스
24.1.2: 입력 연산용 클래스
24.1.2.1: 한-문자 버퍼 사용하기
24.1.2.2: 여러-문자 버퍼 사용하기
24.1.2.3: `streambuf' 객체에서 위치 찾기
24.1.2.4: `streambuf' 객체에서의 여러 `unget' 호출
24.1.3: istream 객체로부터 크기가 고정된 필드 추출
24.1.3.1: 멤버 함수와 예제

24.2: `fork' 시스템 호출

24.2.1: 기본 Fork 클래스
24.2.2: 부모와 자손
24.2.3: 방향전환 심화 연구
24.2.4: `Daemon' 프로그램
24.2.5: `Pipe' 클래스
24.2.6: `ParentSlurp' 클래스
24.2.7: 여러 자손과 통신하기
24.2.7.1: `Selector' 클래스: 인터페이스
24.2.7.2: `Selector' 클래스: 구현
24.2.7.3: `Monitor' 클래스: 인터페이스
24.2.7.4: `Monitor' 클래스: s_handler 배열
24.2.7.5: `Monitor' 클래스: `run' 멤버 함수
24.2.7.6: `Monitor' 클래스: 예제
24.2.7.7: `Child' 클래스

24.3: 비트 연산을 수행하는 함수 객체

24.4: 이항 연산자를 클래스에 추가하기

24.4.1: 승격을 허용하는 이진 연산자

24.d: 이항 연산자를 클래스에 추가하기(C++17)

24.d.a: 연산자만 사용하기
24.d.a.a: 이름공간을 줄 것인가 말 것인가?
24.d.b: CRTP 그리고 연산자 함수 템플릿 정의하기
24.d.c: 삽입과 추출

24.5: 범위-기반의 for-회돌이 그리고 포인터-범위

24.6: 연산자[]()에서 lvalue와 rvalue를 구별하기

24.7: `reverse_iterator' 구현하기

24.8: `bisonc++'와 `flexc++' 사용하기

24.8.1: `flexc++'를 사용하여 스캐너 만들기
24.8.1.1: 파생 클래스 `Scanner'
24.8.1.2: 어휘 스캐너 규격 파일
24.8.1.3: `Scanner' 구현
24.8.1.4: `Scanner' 객체 사용하기
24.8.1.5: 프로그램 빌드하기
24.8.2: `bisonc++'와 `flexc++' 사용하기
24.8.2.1: `bisonc++' 규격 파일
24.8.2.2: `flexc++' 규격 파일
24.8.2.3: 프로그램 빌드하기