cpp23 6

C++23 std::move_only_function으로 소유권 있는 게임 콜백 안전하게 넘기기

게임 코드에서 콜백은 피하기 어렵다. 스킬 캐스팅 완료, 비동기 로딩 완료, 서버 응답 처리, 타이머 만료처럼 "지금은 아니고 나중에 실행할 코드"가 계속 생긴다. 전통적으로는 함수 포인터, std::function, 엔진별 delegate를 많이 쓴다.문제는 콜백이 단순 함수 호출을 넘어 소유권을 함께 가져야 할 때다. 예를 들어 로딩 작업이 끝날 때 임시 버퍼를 넘기거나, 서버 요청 객체를 한 번만 소비하거나, 취소 가능한 작업 핸들을 콜백 안에 묶고 싶을 수 있다. 이때 std::function은 복사 가능해야 하므로 std::unique_ptr 같은 move-only 객체를 캡처한 람다를 담을 수 없다.C++23의 std::move_only_function은 이 빈틈을 메운다. 이름 그대로 복사할..

C#·C++ 모던 2026.07.05

C++23 std::scope_exit로 게임 상태 복구 코드를 안전하게 만들기

게임 코드는 성공 경로보다 실패 경로에서 더 자주 망가집니다. 스킬을 시전하다가 마나만 빠지고 쿨타임이 안 걸리거나, 로딩 중 예외가 나서 임시 플래그가 그대로 남거나, AI 상태를 바꾸다 중간 return 때문에 이동 잠금이 풀리지 않는 식입니다.이런 문제는 대부분 “시작할 때 바꾼 상태를 끝날 때 반드시 되돌린다”는 규칙이 코드에 흩어져 있어서 생깁니다. C++에서는 오래전부터 RAII 패턴으로 해결해 왔고, C++23의 std::scope_exit는 이 패턴을 표준 문법처럼 간결하게 쓸 수 있게 해줍니다.핵심은 간단합니다. 현재 스코프를 빠져나갈 때 실행할 정리 코드를 미리 등록합니다. 성공, 실패, 조기 return 여부와 관계없이 실행되므로 게임 플레이 코드의 “복구 누락”을 줄이는 데 효과적입..

C#·C++ 모던 2026.06.30

C++ 23 std::flat_map으로 게임 룩업 테이블의 캐시 미스 잡기

연관 컨테이너가 필요할 때 C++ 개발자가 가장 먼저 떠올리는 건 std::map이다. 키로 빠르게 찾고, 자동으로 정렬되고, 삽입과 삭제가 O(log n)이다. 교과서적으로는 흠잡을 데가 없다. 그런데 게임 코드에서 매 프레임 수백 번 순회하는 자료구조로 std::map을 쓰는 순간, 프로파일러는 캐시 미스로 새빨갛게 물든다.이유는 알고리즘 복잡도가 아니라 메모리 레이아웃에 있다. std::map은 내부적으로 균형 이진 트리(보통 red-black tree)이고, 노드 하나하나가 힙에 따로 할당된다. 노드들이 메모리 여기저기 흩어져 있으니 순회할 때마다 포인터를 따라가야 하고, CPU는 매번 새 캐시 라인을 읽어와야 한다. 요즘 하드웨어에서 캐시 미스 한 번은 산술 연산 수백 개와 맞먹는 비용이다.C+..

C#·C++ 모던 2026.06.23

C++ 23 std::generator로 게임 웨이브와 절차적 콘텐츠를 lazy 시퀀스로 뽑아내기

웨이브 스포너를 구현해 본 사람이라면 누구나 한 번쯤 비슷한 코드를 짜 봤을 것이다. 현재 웨이브 번호를 멤버 변수로 들고, 매 웨이브가 끝날 때마다 ++currentWave 하고, 다음에 스폰할 적의 종류와 수를 그때그때 switch 나 if 덩어리로 계산한다. 절차적 던전도 마찬가지다. 방 목록을 미리 std::vector 에 전부 채워 넣거나, 인덱스를 손으로 굴리면서 "다음 방"을 꺼내는 상태 머신을 직접 만든다.문제는 이 두 가지가 본질적으로 같은 패턴인데도 매번 손으로 상태 관리 코드를 다시 쓴다는 점이다. "다음 값을 요청하면 그때 계산해서 돌려준다"는 lazy 시퀀스 개념이 게임 로직 곳곳에 있는데, C++ 에는 오랫동안 이걸 깔끔하게 표현할 표준 도구가 없었다.C++ 23 의 std::g..

C#·C++ 모던 2026.06.16

C++23 deducing this로 CRTP 없이 게임 컴포넌트 체이닝 구현하기

게임 엔진 코드를 짜다 보면 컴포넌트나 빌더를 체이닝 방식으로 설정하고 싶을 때가 많다. entity.setPosition(0, 0).setScale(1.5f).enable() 처럼 연속 호출이 가능하면 설정 코드 가독성이 크게 올라가기 때문이다. Unreal Engine의 각종 파라미터 구조체나 커스텀 파티클 빌더를 만들 때 특히 자주 마주치는 패턴이다.문제는 C++20 이전에서 이걸 깔끔하게 구현하려면 CRTP(Curiously Recurring Template Pattern) 를 써야 했다는 점이다. 기능은 동작하지만 기반 클래스 선언이 template 로 시작해야 하고, 메서드마다 static_cast(*this) 를 작성해야 한다. 상속 계층이 2단계만 깊어져도 컴파일 에러 추적이 괴로워진다.C..

C#·C++ 모던 2026.06.09

C++23 std::expected로 게임 코드의 에러 처리 다시 짜기 (예외도 에러코드도 아닌 제3의 길)

게임 엔진 코드에서 에러 처리는 늘 골칫거리다. 에셋 로딩, 파일 파싱, 네트워크 패킷 해석, 셰이더 컴파일까지 "실패할 수 있는 함수"는 도처에 있는데, 정작 C++에서 이걸 깔끔하게 표현할 방법이 마땅치 않았다. 예외(exception)는 대부분의 게임 스튜디오가 -fno-exceptions로 꺼버리는 데다 핫 패스에서 비용이 부담스럽고, 그렇다고 전통적인 에러코드 반환은 결과값과 에러를 한 함수에서 같이 돌려줄 수가 없어 출력 파라미터(out-parameter)를 끌고 다녀야 한다.그래서 많은 코드베이스가 자체 Result / Optional 타입을 굴려왔다. 언리얼의 TOptional, 각 스튜디오의 사내 result 타입, 그리고 절반쯤 동작하는 매크로들. 이제 C++23이 표준 라이브러리로 이..

C#·C++ 모던 2026.05.26