C++23

**C++23**, 공식적으로 **ISO/IEC 14882:2024**,는 C++20에 이어지는 C++ 프로그래밍 언어의 현재 개방형 표준이다. 이 버전의 최종 초안은 N4950이다.

2020년 2월, 프라하에서 열린 C++20 최종 회의에서 C++23에 대한 전체 계획이 채택되었다. C++23의 계획된 기능은 코루틴을 위한 라이브러리 지원, 모듈화된 표준 라이브러리, 실행자(executor), 네트워킹이었다.

C++23에 초점을 맞춘 첫 WG21 회의는 2020년 6월 초 바르나에서 열릴 예정이었으나, 코로나19 범유행으로 인해 취소되었다. 2020년 11월 뉴욕 회의와 2021년 2월 코나(Kona) 회의도 마찬가지였다. 2022년 11월까지 모든 회의는 가상으로 진행되었고, 2022년 11월 회의부터 2023년 2월 최종 회의까지는 하이브리드 형식으로 진행되었다. 이 표준은 2023년 2월 이서콰에서 열린 하이브리드 회의에서 WG21에 의해 기술적으로 최종 확정되었다.

## 현대적인 "Hello, world" 예제
작업 초안에 많은 라이브러리 변경 사항이 적용된 후, 새로운 "Hello, world" 프로그램은 다음과 같다. https://en.cppreference.com/w/cpp/io/println


```cpp
import std;

int main() {
    std::println("Hello, world!");
}
```


## 기능
C++23에 승인된 변경 사항은 다음과 같다.

### 언어
*명시적 `this` 객체 매개변수
*`if consteval`
*다차원 첨자 연산자
*정적 호출 및 첨자 연산자와 정적 람다
*암시적 이동 단순화
*`auto(x)` 및 `auto{x}`
*새로운 전처리기 지시문:
**`#elifdef` 및 `#elifndef`
**`#warning`
*범위 기반 for 루프에서 일부 임시 변수의 수명 연장
*새로운 표준 속성 ``
*상속된 생성자로부터의 클래스 템플릿 인자 추론
*복합 문의 끝에 있는 레이블
*초기화 문 내의 별칭 선언
*`std::size_t` 및 해당 부호 있는 타입에 대한 리터럴 접미사
*리터럴을 포함한 확장 부동 소수점 타입 (조건부 지원)
*널리 람다 표현식의 선택적 `()`
*람다 표현식의 속성
*`constexpr` 변경 사항:
**`constexpr` 함수 내의 비리터럴 변수, 레이블 및 `goto`
**`constexpr` 함수 내에서 상수 표현식으로 사용 가능한 `static` 및 `thread_local` 변수 허용
**`constexpr` 함수는 반환 타입과 매개변수 타입이 리터럴 타입일 필요가 없다.
**핵심 상수 표현식의 요구 사항을 만족하는 호출이 없는 `constexpr` 함수를 작성하는 것이 이제 가능하다.
*`static_assert` 및 `if constexpr`에서 `bool`로의 컨텍스트적 축소 변환
*라인 연결 전 공백 제거
*선언 순서 레이아웃 의무화
*구분된 이스케이프 시퀀스
*이름 있는 유니버설 문자 이스케이프
*텍스트 인코딩 변경 사항:
**이동 가능한 소스 파일 인코딩으로 UTF-8 지원
**일관된 문자 리터럴 인코딩
**문자 집합 및 인코딩
*`this`와 같은 일부 키워드에 새로운 의미 추가..

### 라이브러리
#### 표준 라이브러리 모듈 지원
*표준 라이브러리 모듈 `std` 및 `std.compat`

#### 코루틴 라이브러리 지원
*범위에 대한 동기식 코루틴 `std::generator`
#### 일반 유틸리티 지원
*결과 타입 `std::expected`
*`std::optional` 및 `std::expected`을 위한 모나드 연산
*enum의 기본 값을 가져오는 유틸리티 함수 `std::to_underlying`
*이동 전용 호출 가능 래퍼 `std::move_only_function`
*`std::forward_like`
*`std::invoke_r`
*`std::bind_back`
*`std::byteswap`
*`std::unreachable`: 접근할 수 없는 코드를 표시하는 함수
*`std::tuple`을 다른 튜플 유사 객체와 호환 가능하게 만들었다.
*참조 타입을 반환하는 `std::reference_wrapper`에 대한 `std::basic_common_reference` 특수화 추가
*`std::pair`의 전달 생성자에 대한 기본 인자 추가

#### 컴파일 시간 지원
*`constexpr` 지원:
**`std::type_info::operator==`
** `std::bitset`
** `std::unique_ptr`
** 일부 `<cmath>` 함수
** `std::to_chars` 및 `std::from_chars`의 정수 오버로드
*메타프로그래밍 유틸리티:
**타입 트레잇 `std::is_scoped_enum`, `std::is_implicit_lifetime`, `std::reference_constructs_from_temporary`, 및 `std::reference_converts_from_temporary`.
*비교 개념에 대한 이동 전용 타입 지원 추가

#### 이터레이터, 범위 및 알고리즘 지원
*새로운 범위 변환 함수 `std::ranges::to`
*새로운 제약이 있는 범위 알고리즘:
**`std::ranges::starts_with`
**`std::ranges::ends_with`
**`std::ranges::contains`
**`std::ranges::contains_subrange`
**`std::ranges::find_last` 및 기타 변형
**`iota`, `shift_left` 및 `shift_right`의 범위화된 버전
**범위 폴드 알고리즘
*새로운 `std::ranges::range_adaptor_closure`, 사용자 정의 범위 어댑터 클로저를 정의하기 위한 헬퍼
*새로운 범위 어댑터:
**`std::views::zip` 및 기타 변형
**`std::views::adjacent` 및 기타 변형
**`std::views::join_with`
**`std::views::slide`
**`std::views::chunk`
**`std::views::chunk_by`
**`std::views::as_rvalue`
**`std::views::as_const`
**`std::views::repeat`
**`std::views::stride`
**`std::views::cartesian_product`
**`std::views::enumerate`
*상수 이터레이터, 센티넬 및 범위를 수정하여 `std::ranges::cbegin` 및 기타 유사 유틸리티가 얕은 상수 뷰(예: `std::span`)의 경우에도 상수 이터레이터를 반환하도록 완전히 보장한다.
*비범위 알고리즘의 입력으로 범위 이터레이터
*이동 전용 타입을 허용하도록 범위 어댑터 완화
*일부 뷰의 다중 매개변수 생성자를 `explicit`으로 만들었다.

#### 메모리 관리 지원
*C 상호 운용성을 위한 `std::out_ptr` 및 `std::inout_ptr`
*`std::allocate_at_least` 및 `std::allocator::allocate_at_least`
*암시적 수명 타입에 대한 명시적 수명 관리 함수 `std::start_lifetime_as`
*`std::allocator_traits`의 사용자 특수화 금지

#### 문자열 및 텍스트 처리 지원
*새로운 멤버 함수 및 문자열 타입의 변경 사항:
**`std::basic_string_view::contains` 및 `std::basic_string::contains`
**`std::basic_string` 및 `std::basic_string_view`에 대한 `nullptr`로부터의 생성 비활성화
**`std::basic_string_view`에 대한 명시적 범위 생성자
**`std::basic_string::resize_and_overwrite`
**효율적인 슬라이싱을 위한 `std::basic_string::substr`의 rvalue 참조 오버로드
*범위, 튜플, 문자 및 문자열의 이스케이프된 표현, `std::thread::id` 및 스택 트레이스 포매팅.

#### 진단 지원
*스택 트레이스 라이브러리

#### I/O 지원
*새로운 헤더 `<print>`에서 가져온 서식 있는 출력 함수 `std::print` 및 `std::println`
*새로운 헤더 `<spanstream>`에서 가져온 spanstream 라이브러리(`std::span` 기반 문자열 스트림)
*`std::fstream`에서 독점 모드 지원
*`std::basic_ostream::operator<<(const volatile void*)`

#### 컨테이너 지원
*다차원-스팬 `std::mdspan`
*다른 호환 가능한 범위로부터의 컨테이너 생성 가능성 및 할당 가능성
*평면 집합 및 평면 맵 컨테이너 어댑터
*컨테이너 추론 가이드에서 할당자를 위한 비추론 컨텍스트
*연관 컨테이너에 대한 이기종 삭제 오버로드
*스택 및 큐에서 이터레이터 쌍 생성 허용
*`std::span` 및 `std::basic_string_view`가 사소하게 복사 가능해야 함을 요구

#### C 호환성 지원
*새로운 헤더 `<stdatomic.h>`

### 언어 결함 보고서
*유니코드 표준 부록 31을 사용하는 C++ 식별자 구문
*중복 속성 허용
*람다 후행 반환 타입의 범위 변경
*오버로드된 비교 연산자를 덜 파괴적인 변경으로 만들기
*Volatile 복합 할당의 폐기 해제
*`char8_t`의 호환성 및 이식성 문제 해결
*기존 관행에 맞춰 `wchar_t`에 대한 요구 사항 완화
*상수 표현식에서 `this` 또는 알 수 없는 출처의 일부 포인터 및 참조 허용
*즉시 확장 함수를 즉시 함수로 승격
*인스턴스화되지 않은 템플릿 컨텍스트에서 `static_assert(false)` 허용

### 라이브러리 결함 보고서
*범위 라이브러리의 변경 사항:
**조건부로 빌려온 범위
**입력 범위 어댑터 및 `std::counted_iterator` 수정
**`std::ranges::join_view`에 대한 제약 완화
**`std::ranges::split_view`를 `std::ranges::lazy_split_view`로 이름 변경 및 새로운 `split_view`
**개념 `std::ranges::view`에서 `std::default_initializable` 제약 조건 제거
**소유권을 가진 뷰와 새로운 `std::ranges::owning_view`
**`std::ranges::istream_view` 수정
*텍스트 포매팅 라이브러리 변경 사항:
**`std::basic_format_string`
**컴파일 시간 형식 문자열 검사
**`std::format_to`의 이진 코드 크기 감소
**chrono 포매터에서 로케일 처리 문제 해결
**너비 추정 개선 및 `std::format`의 채움 문자 허용
**비상수 포맷 가능 타입 허용을 위한 형식 인자에서 전달 참조 사용
*완전히 `constexpr`인 `std::variant` 및 `std::optional`
*`std::visit`에서 `std::variant`에서 파생된 타입 지원

### 제거된 기능 및 폐기
제거된 기능:
*가비지 컬렉션 지원 및 (엄격한) 포인터 안전성 (즉, 완화된 포인터 안전성만 의존 가능). 이 최소한의 가비지 컬렉션 지원(및 이를 위해 필요한 포인터 안전성)은 C++11에 추가되었지만, 어떤 컴파일러도 이를 지원한 적이 없으므로 C++23에서 제거되었다. 그러나 이것이 Boehm GC와 같이 C++와 함께 많은 GC 구현이 사용되지 않았다는 것을 의미하지는 않으며, 디버그 모드에서 누수 감지를 위해 (또한 누수 감지에도) 사용될 수 있으며, 이러한 GC는 다른 언어에서 사용하기 위해 종종 C++로 구현된다.
*혼합 와이드 문자열 리터럴 연결.
*인코딩 불가능한 와이드 문자 리터럴 및 다중 문자 와이드 문자 리터럴.

폐기된 기능:
*`std::aligned_storage` 및 `std::aligned_union`
*`std::numeric_limits::has_denorm`

복원된 폐기된 기능:
*첨자 표현식에서 쉼표 연산자 사용은 더 이상 폐기되지 않았지만, 오버로드 가능한 n-adic `operator[]`를 지원하도록 의미가 변경되었다.
*C 헤더 (C와의 호환성을 위한 해당 `<*.h>` 헤더)

## 기술 사양으로 발행됨
* Concurrency TS v2

## 컴파일러 지원
* 클랭은 2021년 버전 13부터 2024년 버전 18까지 C++23 부분 지원을 점진적으로 추가했으며, 옵션 `-std=c++23`을 통해 사용할 수 있다.
* GCC는 2021년 버전 11에서 옵션 `-std=c++2b` 또는 `-std=c++23`을 통해 C++23의 부분적, 실험적 지원을 추가했다. 또한 실험적인 C++23 지원 외에 GNU 확장을 활성화하는 옵션 `-std=gnu++2b`도 있다.

## 역사
대면 WG21 회의가 없는 상황에서, 다음 변경 사항들은 여러 가상 WG21 회의 후 적용되었으며, 여기서 여론조사(straw poll)를 통해 승인되었다.

### 2020년 11월
2020년 11월 9일 가상 WG21 회의 후 다음 사항들이 추가되었으며, 여론조사를 통해 승인되었다.
* `std::[[size_t]]` 및 해당 부호 있는 타입에 대한 리터럴 접미사
* 주어진 부분 문자열 또는 문자를 문자열이 포함하는지 확인하는 `std::basic_string` 및 `std::basic_string_view`에 대한 멤버 함수 
* Boost.Stacktrace를 기반으로 하는 스택 트레이스 라이브러리 ()
* 타입 트레잇 
* C 원자(atomic)와의 상호 운용성을 위한 헤더 

### 2021년 2월
2021년 2월 22일 가상 WG21 회의 후, 다음 기능들이 추가되었으며 여론조사를 통해 승인되었다.
* 람다 표현식에서 불필요한 빈 매개변수 목록  제거.
* 입력 범위 어댑터 및  수정.
* 에 대한 요구 사항 완화.
* 에서 파생된 클래스에 대한 .
* 잠금 가능 객체를 잠근다.
* 조건부로 빌려온 범위.
* .

### 2021년 6월
2021년 6월에 열린 여름 ISO C++ 표준 본회의 가상 회의 후, 새로운 기능과 결함 보고서가 여론조사를 통해 승인되었다.
* Consteval if ().
* 로의 컨텍스트적 축소 변환.
* 중복 속성 허용.
*  기반 문자열 스트림 ().
*  및 .
* ,  및 에 대한 .
*  (스택) 및  (큐)에 대한 이터레이터 쌍 생성자.
* 범위 라이브러리의 몇 가지 변경 사항:
** 임의 범위에 대한 일반화된  및 .
** 를 로 이름 변경 및 새로운 .
** 에 대한 제약 완화.
** 개념 에서  제약 조건 제거.
** 에 대한 범위 생성자.
* 로부터의  및  생성 금지.
* .
*  개선.
* 의 전달 생성자에 기본 인자 추가.

### 2021년 10월
2021년 10월에 열린 2021년 가을 ISO C++ 표준 본회의 가상 회의 후, 새로운 기능과 결함 보고서가 여론조사를 통해 승인되었다.
* 비리터럴 변수, 레이블 및 `goto`가  함수에 허용되었지만, 컴파일 시간에 평가하는 것은 여전히 잘못된 형식이다.
* 명시적  객체 매개변수.
* 문자 집합 및 인코딩 변경 사항.
* 새로운 전처리기:  및 . 두 지시문은 C23 (C 언어 업데이트) 및 GCC 12에 추가되었다.
* 초기화 문에서 별칭 선언 허용.
* 다차원 첨자 연산자 오버로드 (예: ).
* 언어 내 decay copy:  또는 .
* 텍스트 포매팅 라이브러리 변경 사항:
** chrono 포매터에서 로케일 처리 문제 해결.
**  유사 타입을 허용하기 위해 형식 인자에서 전달 참조 사용.
* 와 동등한 타입 별칭  추가.
* 범위 라이브러리 변경 사항:
** 뷰의 정제된 정의.
** 함수 템플릿 를 별칭 템플릿 ,  및 사용자 정의 지점 객체 으로 대체.
**  범위 어댑터 패밀리:
*** 
*** 
***  (및 는 와 동등)
***  (및 는 와 동등)
* .
* 에 대한 모나드 연산.
* 멤버 함수 템플릿 .
*  포인터 출력 ().
* .
* 연관 컨테이너에 대한 이기종 삭제 오버로드.
*  및 의 모든 특수화는 사소하게 복사 가능하다.
* 에 조건부  사양 추가.
* 정수 클래스 타입의 사양 및 사용 개편.
* C 헤더 명확화. "헤더는 C++로만 유효해야 하는 코드에서는 유용하지 않다. 따라서 C 헤더는 C++ 표준 라이브러리에서 완전히 지원되고 폐기되지 않은 부분으로 제공되어야 하지만, 다국어 상호 운용 코드(polyglot interoperability code)가 아닌 코드에서는 사용이 권장되지 않는다. [..] 이 제안은 C 헤더를 더 이상 폐기되지 않도록 하여 향후 제거될 formal threat를 없앤다. 순수 C++ 코드에서 C 헤더 사용을 자제하도록 하는 실질적인 권장 사항은 이제 규범적 권장 사항으로 명시적으로 명시된다."

### 2022년 2월
2022년 2월 7일 가상 WG21 회의 후, 다음 기능들이 추가되었으며 여론조사를 통해 승인되었다.
* 람다의 함수 호출 연산자에 속성 허용
* 
* `cmath` 및 `cstdlib`에 대한 
* 접근할 수 없는 코드를 표시하는 함수
* 
* 임시 객체에 대한 참조 바인딩을 감지하는 타입 트레잇
* 를 로 만들기
* 사용자 정의 범위 어댑터에 대한 파이프 지원
* ,  및 
* 
* 윈도잉 범위 어댑터:  및 
* 

### 2022년 7월
2022년 7월 25일 가상 WG21 회의 후, 다음 기능 및 결함 보고서가 추가되었으며 여론조사를 통해 승인되었다.
* 표현식에서 동일성 재작성을 덜 파괴적인 변경으로 만들었다.
*  변수에 대한 비트별 할당 폐기 해제를 되돌렸다.
*  전처리기 지시어를 추가했다.
* 인코딩 불가능한 와이드 문자 리터럴과 다중 문자 와이드 문자 리터럴을 제거했다.
* 레이블이 복합 문의 끝에 나타날 수 있도록 허용했다.
* 8진수 및 16진수에 대한 중괄호로 구분된 이스케이프 시퀀스와 유니버설 문자 이름을 추가했다.
*  함수가 상수 표현식이 될 수 없도록 허용했다.
* C++20의 일부 암시적 이동 규칙을 단순화하고 rvalue 참조를 반환할 때 암시적 이동을 허용했다.
* 이름으로 유니코드 문자를 지정하는 방법을 추가했다. 예를 들어, 
*  및 람다가 이 될 수 있도록 허용했다.
* <code>this</code> 포인터와 알 수 없는 출처의 참조가 상수 표현식에 나타날 수 있도록 허용했다.
* 세 가지 표준 부동 소수점 타입 외에 확장 부동 소수점 타입을 정의할 수 있도록 구현을 허용했다. 헤더 `<stdfloat>`를 통해 접근 가능한 이러한 확장 타입에 대한 타입 별칭 `std::float16_t`, `std::float32_t`, `std::float64_t`, `std::float128_t`, `[[Bfloat16 부동소수점|std::bfloat16_t]]`와 해당 리터럴 접미사 `f16` `f32` `f64` `f128` `bf16` 또는 `F16` `F32` `F64` `F128` `BF16`을 추가하고, float를 인수로 받는 다양한 표준 라이브러리 함수에 오버로드를 추가했다.
* 컴파일러가 제공된 표현식이 참이라고 가정하여 최적화를 허용하는  속성을 추가했다.
* 소스 파일의 이동 가능한 인코딩을 제공하기 위해 UTF-8 소스 파일 지원을 의무화했다.
*  및  배열을 UTF-8 문자열 리터럴로 초기화할 수 있도록 허용했다.
* 확장 문자 집합의 모든 문자를 인코딩할 수 있다는 에 대한 요구 사항을 제거하여, UTF-16을 와이드 문자열 리터럴에 사용할 수 있도록 효과적으로 허용했다.
* `std::span`과 유사한 다차원 배열 뷰인 `std::mdspan`을 추가했다.
*  및 이 표준 라이브러리에 추가되었다.
* 표준 출력에 서식 있는 텍스트를 출력하기 위한  및  함수를 추가했다.
* 표준 라이브러리를 가져오기 위한 이름 있는 모듈  및 를 제공한다.
* `[[fopen]]`의 "x" 플래그와 유사하게 독점 모드 `fstream`에 대한 지원을 추가했다.
* `std::format`이 범위, 튜플 및 기타 컨테이너를 처리할 수 있도록 허용했다.
* `std::forward_like`를 추가했다.
* `std::string::substr`가 이동 시맨틱스를 사용하도록 만들었다.
* 를 모델링하는 코루틴 생성자를 구현하는 를 추가했다.
* , , , , .
* 새로운 알고리즘 추가: ,  및 범위 폴드 알고리즘.
* `std::tuple`을 다른 튜플 유사 객체와 호환 가능하게 만들었다.
* 암시적 수명 타입에 대한 명시적 수명 관리.
* `std::bitset` 및 `std::to_chars`와 `std::from_chars`의 정수 오버로드를 -호환 가능하게 만들었다.
* 비교 개념에 대한 이동 전용 타입 지원 추가.
* 비범위 알고리즘의 입력으로 범위 이터레이터.
* 이동 전용 타입을 허용하도록 범위 어댑터 완화.

### 2022년 11월
2022년 11월 7일 하이브리드 WG21 회의 후, 다음 기능 및 결함 보고서가 추가되었으며 여론조사를 통해 승인되었다.
* 가 이 될 수 있도록 허용했다.
* 상수 표현식에서 사용 가능한 경우,  및  변수가  함수에 나타날 수 있도록 허용했다.
* 이 위로 전파되도록 했다. 즉, 특정 기존  함수는 컴파일 시간에만 호출될 수 있는 경우  함수가 된다.
* 범위 기반  루프의 for-range-initializer에 나타나는 임시 변수의 수명을 전체 루프를 포함하도록 연장했다.
* (비트별이 아닌 모든) 복합 할당을  변수에 대한 폐기 해제를 되돌렸다.
* 에 대한 모나드 함수.
* 네이티브 유니코드 API가 사용되는 경우 의 출력을 기본 스트림과 동기화한다.

### 2023년 2월
2023년 2월 6일부터 11일까지 열린 최종 하이브리드 WG21 회의 후, 다음 기능 및 결함 보고서가 추가되었으며 여론조사를 통해 승인되었다.
* 유니코드 표준 참조.
* 적절한 평탄화를 위한 스태싱 이터레이터 스태싱.
* `views::enumerate`
* 뷰의 다중 매개변수 생성자를 명시적으로 만들기
* 범위를 약간 더 완화
* `std::format`의 이스케이프 개선
* `std::format`의 너비 추정 개선
* `std::format` 채움 문자 허용
* `thread::id` 및 `stacktrace` 포매팅
* 타입 트레잇 `std::is_implicit_lifetime`
* `std::reference_wrapper`의 `std::common_reference_t`는 참조 타입이어야 한다.
* `std::allocator_traits`의 사용자 특수화 금지
* `std::pmr::generator`
* `std::numeric_limits::has_denorm` 폐기
* `std::barrier`의 페이즈 완료 보장

## 같이 보기
* C++23 기능에 대한 컴파일러 지원

## 각주

분류:알골 프로그래밍 언어 계열
분류:C++
분류:C++ 프로그래밍 언어 계열
분류:정적 타입 프로그래밍 언어
분류:고급 프로그래밍 언어