modern-cpp 4

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::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