C++ 프로그래밍

C++ optional의 활용

하늘흐늘 2021. 10. 24. 13:14
반응형

C++ 17에 추가된 유용한 클래스 중에 optional이 있습니다. 해당 객체는 값을 리턴할 때 값이 없음을 표현하기에 유용합니다.
예제로 optional의 활용을 살펴보기로 하겠습니다. 참고로 optional을 사용하기 위해서는, 즉 아래 예제 코드를 컴파일 하기 위해서는 컴파일러에서 C++ 17 표준을 지원해야 하며 Visual Studio 컴파일러 같은 경우 C++ 17을 지원하기 위한 컴파일 옵션을 설정하여 주어야 합니다.

#include <iostream>
#include <vector>
#include <optional>

using namespace std;


class test_optional
{
private:
	vector<int> data_{ 10, 20, 30 };

public:
	int getByIndex1(int index)
	{
		if (index < 0 || data_.size() <= index)
		{
			return -1;
		}

		return data_[index];
	}

	optional<int> getByIndex2(int index)
	{
		if (index < 0 || data_.size() <= index)
		{
			return std::nullopt;
		}

		return data_[index];
	}
};



int main(int argc, char* argv[])
{
	test_optional test;

	int ret1 = test.getByIndex1(3);
	if (ret1 == -1)
	{
		cout << "data is not found by test.getByIndex1(3)" << endl;
	}

	optional<int> ret2 = test.getByIndex2(3);
	if (!ret2.has_value())
	{
		cout << "data is not found by test.getByIndex2(3)" << endl;
	}

	optional<int> ret3 = test.getByIndex2(4);
	if (ret3 == std::nullopt)
	{
		cout << "data is not found by test.getByIndex2(4)" << endl;
	}

	optional<int> ret4 = test.getByIndex2(1);
	if (ret4.has_value())
	{
		cout << ret4.value() << endl;
	}
}

결과는 아래와 같습니다.

data is not found by test.getByIndex1(3)
data is not found by test.getByIndex2(3)
data is not found by test.getByIndex2(4)
20

예제로 getByIndex1 함수와 같은 경우는 기존 C++ 코드에서 흔히 보는 예로 값이 없을 경우 -1을 리턴하는 예제입니다. 만약 포인터를 리턴하는 함수였다면 nullptr을 리턴했을 것입니다. 보통 기존 함수는 -1을 값이 존재하지 않는 경우를 의미한다고 정의하여 코딩하였습니다. 이 때 -1 값이 존재하는 경우 버그가 생기거나 다른 방법을 사용하여야 하였습니다. 
이런 경우에 활용하기에 좋은 객체가 optional입니다. optional은 값을 리턴하면서 값이 없음을 표시할 수 있기 때문입니다. getByIndex2 함수는 getByIndex1과 같은 기능을 하지만 optional을 활용하였습니다. 값이 있는 경우에는 getByIndex1과 동일하게 리턴하며 없는 경우에는 std::nullopt을 리턴하여 값이 없음을 표시합니다. 
optional로 리턴받는 경우 값이 존재하는지를 판단하는 방법은 2가지가 있습니다. 리턴값이 std::nullopt인지를 체크하는 방법과 has_value()을 체크하는 방법입니다. 값이 있는지를 확인하였으면 value()함수로 값을 가져오면 됩니다.

반응형