CodeNote
Coding Note
CodeNote
전체 방문자
오늘
어제
  • 전체 보기 (35)
    • C++ (33)
      • Modern C++ (12)
      • Modern C++ STL (0)
      • Thread (16)
      • Thread (Async) (5)
    • 디자인패턴 (0)
    • Algorithm (2)
    • Electron (0)
    • Python (0)

블로그 메뉴

  • 홈
  • Github
  • 태그
  • 방명록

공지사항

인기 글

태그

  • C++
  • 자료구조
  • LOCK
  • C++ #Memory
  • mutex
  • Free

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
CodeNote

Coding Note

[C++17] std::optional
C++/Modern C++

[C++17] std::optional

2022. 10. 31. 17:38

std::optional

std::optional은 C++17 부터 추가되었으며  변수나 오브젝트가 있을 수도 있고 없을수도 있다는 뜻을 의미한다.


예시로 다음 타입 스크립트 코드를 보면,

function f(x: number, y? : number)  
{ 
	return x + (y ?? 0)
}


여기서 y뒤에 물음표가 optional 인데

  • y 값이 정의되어있으면 y를 그대로 사용하여 x에 더한다.
  • y 값이 정의되어있지 않다면 0을 가져다 x에 더한다.

즉, 값이 있을수도 있고 없을수도 있다라는 것이다.

 

Example Code : Primitive Type 예제

#include <optional>
std::optional<int> divide(int a, int b)
{
	if (b == 0)
	{
		return std::nullopt; // 정의될 수 없을 때는 nullopt을 리턴한다.
	}
	return a / b;
}

int main()
{
	const auto ans = divide(10, 1);
	if (answer) // 데이터 타입은 int의 Optional
	{
		std::cout << answer.value() << std::endl;
	}
	else
	{
		//std::cout << "no value" << std::endl;
		std::cout << answer.value_or(0) << std::endl; // Default Value를 리턴해주는 것도 가능하다.
	}
 }

이러한 std::optional은 오브젝트를 사용해서 정의할 수도 있다.

 

Example Code : Object 정의

std::optional<Cat> cat;
if (!cat) 
{
    std::cout << "no cat yet" << std::endl;
}

이와 같은 방식으로 정의할 수 있는데 아직은 고양이 오브젝트가 없기 때문에 no cat yet이 출력된다.

처음에 고양이를 만들 때 오브젝트를 넣어줘야한다.

 

std::optional<Cat> cat{Cat()};
if (!cat)
{
    std::cout << "no cat yet" << std::endl;
}

위 코드처럼 고양이 오브젝트를 만들어서 넘겨줄 수 있지만 문제가 있다. 이러한 방식은 임시 Cat 오브젝트가 만들어지고 move constructor를 통해서 초기화를 한다. 쓸데없이 고양이를 한 번 생성한 후에 move constructor를 사용하고 있기 때문에 효율적인 방법은 아니다.

 

std::optional<Cat> cat{std::in_place};
if (!cat)
{
    std::cout << "no cat yet" << std::endl;
}
else
{
    std::cout << "cat is ready" << std::endl;
    cat->print(); // 화살표를 통해 호출
}

이 때, std::in_place라는 옵션을 넘겨주게 되면 optional이라는 공간안에 바로 고양이 오브젝트를 만들 수 있게 된다.

 

Memory model

int num = 10;
std::optional<int> num2{ 20 };

위와 같은 optional 코드를 사용했을 때 메모리 모델이 어떻게 되는지 확인해보면,

Memory View

std::optional 변수는 왼쪽에 데이터 값 오른쪽 공간에 Valid한지 Valid하지 않은지 구분해 줄 수 있는 정보가 들어있다. 굉장히 간단한데 이게 optional 동작의 기본 원리의 전부이기 때문에  퍼포먼스에 유의미한 결과를 미치지는 않는다. std::pair보다는 코드 가독성이 좋아지기 때문에 C++ 17 이상을 지원한다면 사용을 고려하는 것이 좋다.

'C++ > Modern C++' 카테고리의 다른 글

[C++17] std::variant  (0) 2022.11.07
[C++] Union  (0) 2022.11.04
[C++] 가상함수 원리  (0) 2022.10.24
[C++] attributes(속성)  (0) 2022.10.13
[C++] Perfect forwarding  (0) 2022.10.05
    'C++/Modern C++' 카테고리의 다른 글
    • [C++17] std::variant
    • [C++] Union
    • [C++] 가상함수 원리
    • [C++] attributes(속성)
    CodeNote
    CodeNote
    기록 블로그

    티스토리툴바