클래식 C++에 익숙해서 모던 C++ 변화 시기에 바닥에 뭍어두고 Rust 학습을 했었는데 흐릿해지니 충격도 줄어드는 것 같다.
C++ 26에서 큰 변화가 있을거라는데, 메모리 안정성을 높인다니. 여전하다.
그래도 20대 전후를 함께한 친구인데 언어 비교를 위해 다시 파내본다.
Modern C++ Features (C++11, C++14, C++17, C++20, C++23)
이 문서는 C++11부터 C++23까지 표준에 도입된 주요 언어 및 라이브러리 기능을 정리하고, 예제 코드를 통해 사용법을 설명합니다.
목차
- C++11
- auto 키워드
- 범위 기반 for 문
- 스마트 포인터 (
std::unique_ptr
,std::shared_ptr
) nullptr
- 람다 표현식
- 이동 시맨틱 (rvalue 참조,
std::move
) - 기타:
static_assert
,constexpr
,enum class
- C++14
- 반환형 자동 추론 (generic lambdas)
std::make_unique
std::integer_sequence
- 마리얼라이즈 사용자 지정 리터럴
- C++17
- 구조 분해 바인딩 (structured bindings)
if constexpr
std::optional
,std::variant
,std::any
- 병렬 알고리즘
- C++20
- 개념 (concepts)
- 범위 라이브러리 (ranges)
- 코루틴 (coroutines)
consteval
및constinit
std::span
- C++23
std::expected
std::print
deducing this
std::flat_map
,std::flat_set
C++11
1. auto 키워드
타입을 컴파일러가 자동으로 추론합니다.
int x = 42;
auto y = x; // y는 int
auto z = 3.14; // z는 double
2. 범위 기반 for 문
컨테이너 순회가 간결해집니다.
std::vector<int> v = {1, 2, 3};
for (auto& elem : v) {
std::cout << elem << std::endl;
}
3. 스마트 포인터
std::unique_ptr
: 소유권을 단독으로 관리std::shared_ptr
: 참조 계수 기반 공유 소유권auto p = std::make_unique<int>(10); auto q = std::make_shared<std::string>("Hello");
4. nullptr
포인터 초기화 시 명확한 null 값을 사용
int* p = nullptr;
5. 람다 표현식
익명 함수 객체로 콜백 간결화
auto add = [](int a, int b) { return a + b; };
std::cout << add(2, 3) << std::endl; // 5
6. 이동 시맨틱
rvalue 참조(T&&
)와 std::move
로 자원 이동 최적화
std::string s1 = "big_data";
std::string s2 = std::move(s1); // s1은 빈 문자열이 됨
7. 기타
static_assert
: 컴파일 타임 검증constexpr
: 컴파일 타임 상수 함수/변수enum class
: 범위 지정 열거형static_assert(sizeof(void*) == 8, "64-bit required"); constexpr int square(int x) { return x * x; } enum class Color { Red, Green, Blue };
C++14
1. 반환형 자동 추론 (generic lambdas)
람다 매개변수에 auto
사용 가능
auto mul = [](auto a, auto b) { return a * b; };
std::cout << mul(2, 3.5) << std::endl; // 7
2. std::make_unique
C++11에는 없던 유니크 포인터 생성기
auto p = std::make_unique<int[]>(5);
3. integer_sequence
템플릿 메타프로그래밍 편의
template<std::size_t... I>
void print_seq(std::index_sequence<I...>) {
((std::cout << I << " "), ...);
}
print_seq(std::make_index_sequence<5>{}); // 0 1 2 3 4
4. 사용자 지정 리터럴
_s
등 편의 리터럴
using namespace std::string_literals;
auto str = "hello"s; // std::string
C++17
1. 구조 분해 바인딩
튜플, pair, 배열 해체
std::pair<int, int> pr{1, 2};
auto [a, b] = pr;
2. if constexpr
컴파일 타임 조건 분기
template<typename T>
void func(T t) {
if constexpr (std::is_integral_v<T>)
std::cout << "정수 타입" << std::endl;
else
std::cout << "비정수 타입" << std::endl;
}
3. std::optional, std::variant, std::any
안전한 값 또는 다형성 타입 처리
std::optional<int> opt;
opt = 5;
if (opt) std::cout << *opt << std::endl;
4. 병렬 알고리즘
단일 헤더 <algorithm>
에서 지원
std::vector<int> v = {5,3,1,4,2};
std::sort(std::execution::par, v.begin(), v.end());
C++20
1. 개념 (Concepts)
템플릿 제약 조건 선언
template<std::integral T>
T add(T a, T b) {
return a + b;
}
2. 범위 라이브러리 (Ranges)
파이프라인 스타일 처리
#include <ranges>
auto v2 = v | std::ranges::views::filter([](int x){ return x%2==0; })
| std::ranges::views::transform([](int x){ return x*2; });
3. 코루틴 (Coroutines)
비동기/제너레이터 작성
#include <coroutine>
// 간단한 generator 예제 생략
4. consteval, constinit
consteval
: 반드시 컴파일 타임 평가constinit
: 초기화 시 consteval이 아닌 상수 보장consteval int ct() { return 42; } constinit int ci = ct();
5. std::span
연속 버퍼 뷰
void process(std::span<int> data) { /* ... */ }
int arr[] = {1,2,3};
process(arr);
C++23
1. std::expected
오류 처리 및 값 반환 조합
std::expected<int, std::string> divide(int a, int b) {
if (b == 0) return std::unexpected("division by zero");
return a / b;
}
2. std::print
편리한 콘솔 출력
#include <print>
std::print("Hello, {}!\n", "World");
3. deducing this
멤버 함수 선언에서 this
타입 자동 추론
struct S {
auto func(this auto&& self) { return self.value; }
int value;
};
4. std::flat_map, std::flat_set
연속 메모리 기반 맵/셋
std::flat_map<int, std::string> fm = {{1,"one"},{2,"two"}};
'개발 > C++ (98,03,11,14,17,20,23)' 카테고리의 다른 글
Modern C++ : enum vs enum class (98, 11) (1) | 2025.08.02 |
---|