std::optional<T> 는 이번에 C++17 부터 표준으로 들어오게 된 건데
원래는 boost 에 있었음
뭐냐하면 하스켈의 Maybe 나 C# 의 Nullable 스칼라의 뭐더라..
하여튼 얘네를 C++ 용으로 구현한 거임
std::optional<T> 자체는 null 값이랑 T 값을 가질 수 있는 union,
C++17 식으로 말하면 std::variant 인데,
기본적으로 유니온이나 variant 와의 차이가 있다면,
인터페이스가 편하다는 것
std::optional<T> 가 만약 null 값을 가지고 있다면 그 인스턴스 자체는 bool 값으로 false 가 됨
std::optional<T>maybe;
if(maybe)
/* statement */
이런식으로 하면 만약 maybe 에 값이 있으면 true 가 되고 값이 없으면 false 가 됨
std::optional<T> 의 T 를 가지고 싶으면 get() 이었나 를 하면 됨
자 여기까지는 이게 왜 획기적인 물건인지 잘 감이 안 오지만,
C 에서 만약 이런걸 한다고 칩시다.
T function(U);
이 때 function의 연산의 성공 여부와 실패 여부에 따라 T 를 줄 수도 있고 안 줄 수도 있으면
크게 2가지 구현 방법이 있음
T : _Bool , U: T* 로 쓰는 방법과,
T : T* 로 쓰는 방법
후자의 경우 이렇게 구현하게 됨
T* function(U)
function 내부의 연산이 성공한다면
T* 는 의미 있는 곳을 가리킬테고,
아니라면 T* 는 NULL 을 가리킬 것임
이것의 심각한 문제점은 일단,
1. int 나 char 같은 것을 반환하고 싶어도 T* 는 포인터 타입이기 때문에 반드시 힙에다가 할당을 해야됨
그리고 말할 필요도 없겠지만 힙에다 할당을 하는건 비쌈...
2. 그리고 사용자는 이걸 받아서 반드시 해제를 해야되고,
3. function 을 사용하는 사람은 이게 NULL 포인터일 수도 있다는 것을 알고서 반드시 널체킹을 해야됨
따라서 function_nullable 식으로 쓰거나 도큐멘테이션에 빨간 글씨로 커다랗게 명시를 해야겠지
전자의 경우 이렇게 구현함
_Bool function(T* t)
이 경우에 연산이 성공하면 _Bool 은 TRUE 가 될테고 아니면 FALSE 가 되겠지
위와 다르게 이 방식이 갖는 장점은,
function의 연산이 성공할 수도 있고 실패할 수도 있다는게 타입으로 명시가 된다는거.
연산의 결과물이 굳이 힙에 할당될 필요는 없다는거
하지만 문제는 반환 인자를 사용자가 제공해야되고,
일반 인자들이랑 반환 인자들이 섞인다는거 등등
C++ 에서도 이런 문제는 C 문법을 사용하고 있는 만큼 자연스럽게 발생하고 있어서,
힙 할당을 최대한 지양하려는 최근 분위기에 맞지 않는다는 점이 있었지
보통은 사용자가 반환할 객체를 생성한 다음에 레퍼런스로 넘겨주는 식..
하지만 사용하지 않을 수도 있는 객체를 반드시 생성한다는 점에서 당연히 오버헤드가 있는거고
하여튼 불편한 점들이 여기저기에 있었음
나의 경우에는 최근까지 std::pair<bool, T> 를 반환해서 사용자가 bool 을 확인하게 하는 식의 코드를 짰는데,
T를 반드시 생성해야된다는 점이 굉장히 불만이었음
하지만 std::optional<T> 를 사용하면 모든 점이 해결됨
1. 반환이 널 값을 가질 수 있다는 것이 명시적임
2. std::optional<T>는 T를 반드시 스택에 할당한다는 보장이 있어서 힙할당보다 성능이 좋음 (확인해보지는 않음)
3. 일반 인자 -> 반환 형태로 함수를 훨씬 순수하게 사용할 수 있음
그 외에도, 어떤 값을 수정할 때 flag 를 운용해야되는 경우라던지,
이럴 때 flag를 사용하지 않는다는 점도 있다는걸 최근에 사용하면서 발견함
하여튼 매우 좋다
C++17 은 함수형 프로그래밍 업데이트라는 점을 실감하게 해주는 점임

개추
호오 확실히 좋네
쩌는구먼!
호오...
[정보] 유니온에도 메서드가 달려서 요걸 직접 만들어 볼 수 이따
스칼라 Option, 스위프트 Optional 등.
개추개추
c++ 이런거보면 점점 성능보다 생산성중시하는 언어들을 따라가는것같음