기존에는 함수의 반환값, 인자값을 예외값이나 기본값을 아래와 같이 지정해주었습니다.


int GetValue(bool flag = false)
{
	if (flag)
	{
		return 100;
	}
	else
	{
		return -1;
	}
}

auto someVal = GetValue();
if (someVal == -1)
	std::cout << someVal << std::endl;


-1이나 0등을 예외값으로 두고, 이 값이 반환값으로 들어오면 예외처리를 하거나 했죠. 함수에 인자값을 줄 때도, 기본값을 설정해서 사용하곤 했습니다.

또는 아래와 같이 std::pair를 이용해 논리적인 형태로 예외값을 처리 하는 방법도 있었죠.


std::pair<bool, int> GetValue(bool flag = false)
{
	if (flag)
	{
		return std::make_pair(true, 100);
	}
	else
	{
		return std::make_pair(false, 0);
	}
}

auto someVal = GetValue(true);
if (someVal.first)
	std::cout << someVal.second << std::endl;


C++17에서 추가된 std::optional 을 사용하게 되면, 아래와 같은 코드가 가능해집니다.


std::optional<int> GetValue(bool flag)
{
	if (flag)
	{
		return 100;
	}
	else
	{
		return std::nullopt;
	}
}

auto someVal = GetValue(false).value_or(100);
std::cout << someVal << std::endl;


std::optional 덕분에 굉장히 직관적인 코드가 되었습니다. 함수에서는 예외값을 std::nullopt로 던져주게 되고, 반환값을 처리하는 곳에서는 std::optional의 멤버 함수인 value_or() 함수를 통해 예외값인 경우 지정해준 기본값을 대입하게 되고, 예외값이 아닌 정상적인 값이면 해당값을 대입하게 됩니다.


또한 반환값을 has_value나 단순하게 if (someVal) 검사로 값이 존재하는지 확인할 수도 있습니다.


참고: https://blogs.msdn.microsoft.com/vcblog/2018/09/04/stdoptional-how-when-and-why/

참고: https://en.cppreference.com/w/cpp/utility/optional

+ Recent posts