Coroutine 상태가 할당되면, 해당 할당이 힙에서 발생할 수도 있습니다.
( 힙에 발생해야한다고 생각해야하지만, 컴파일러가 최적화 할 수도 있습니다. )
만약 힙에서 발생하고, 우리가 만든 promise_type이 get_return_object_on_allocation_failure 을 선언해놨다면,
non-throwing 버전의 new 연산자가 검색됩니다.
만약 Coroutine 할당에 실패하면, 즉시 예외가 발생하지 않습니다. 대신
컴파일러는 호출자쪽의 get_return_object_on_allocation_failure 함수를 호출합니다.
그러므로 다음과 같은 정적 멤버 함수를 promise_type에 선언 및 정의 합니다.
우리의 resumable 은 default 생성된 coroutine_handle 을 지원하지 않기 때문에 ( from_promise ) 예외처리를 해야한다.
-> 우리는 handle을 사용하기전에, handle 할당이 실패했는지도 검사하지 않기 때문에.
우리가 작성한 func() 함수에 마우스를 가져다 대면, operator new 가 연결됨을 볼 수 있습니다.
우리가 promise_type::operator new 를 재정의 하고, 할당 실패를 알려준다면, bad_alloc을 던집니다.
코루틴의 반환 ( co_return )
앞에서 작성한 것과 같이, co_return 을 통하여 Coroutine에서 값을 반환할 수 있습니다. 하지만 이를 위해서 개발자가 일부 추가 지원을 해야 합니다.
일단, co_return 키워드가 발생할 때 co_return이 어떻게 작동하는지를 컴파일러 생성 코드 종류로 파악하면 다음과같다.
1. 값의 반환이 없을 때
이미 우리의 promise_type은 return_void를 작성해놨으므로, 더 이상 작성할 필요가 없습니다.
2. 값의 반환이 있을 때
우리의 promise_type은 return_value가 없으므로, 작성해야 합니다.
[ 참고 : return_void 와 return_value 둘 다 정의할 순 없습니다. ]
실제로, coroutine_handle이 promise에 대한 정보를 가지고 있으므로, 이를 통해 값을 얻어냅니다.
이제 resumable 과 func 그리고 main을 수정합니다.
이렇게 하면 코루틴내에서 값을 반환할 수 있으며, coroutine_handle 의 promise 접근을 통해 값을 받아낼 수 있습니다.
[참고]
호출 스택을 통해 Coroutine의 초기화를 확인할 수 있으며
Coroutine_handle을 통해 suspend point를 확인할 수 있습니다.
'C++ > Modern' 카테고리의 다른 글
C++20) Concepts ( 콘셉트, 개념 ) - 1 (0) | 2020.11.25 |
---|---|
C++20) Coroutine ( 코루틴 ) - 3 (0) | 2020.08.23 |
C++20) Coroutine ( 코루틴 ) - 1 (0) | 2020.08.20 |
C++20) Designated Initializer ( 지정된 초기화 ) (0) | 2020.08.19 |
C++17) std::variant (0) | 2019.02.28 |