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" 프로그램은 다음과 같다. 

import std;

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

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

 언어 
명시적 this 객체 매개변수
if consteval
다차원 첨자 연산자
정적 호출 및 첨자 연산자와 정적 람다
암시적 이동 단순화
auto(x) 및 auto{x}
새로운 전처리기 지시문:
#elifdef 및 #elifndef
#warning
범위 기반 for 루프에서 일부 임시 변수의 수명 연장
새로운 표준 속성 [[assume(expression)]]
상속된 생성자로부터의 클래스 템플릿 인자 추론
복합 문의 끝에 있는 레이블
초기화 문 내의 별칭 선언
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 참조를 반환할 때 암시적 이동을 허용했다.
 이름으로 유니코드 문자를 지정하는 방법을 추가했다. 예를 들어, 
  및 람다가 이 될 수 있도록 허용했다.
 this 포인터와 알 수 없는 출처의 참조가 상수 표현식에 나타날 수 있도록 허용했다.
 세 가지 표준 부동 소수점 타입 외에 확장 부동 소수점 타입을 정의할 수 있도록 구현을 허용했다. 헤더 <stdfloat>를 통해 접근 가능한 이러한 확장 타입에 대한 타입 별칭 std::float16_t, std::float32_t, std::float64_t, std::float128_t, 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++ 프로그래밍 언어 계열
분류:정적 타입 프로그래밍 언어
분류:고급 프로그래밍 언어