C++에서 여러값을 리턴해야 하는 경우

들어가며

코드를 작성하다 보면 함수에서 여러 값을 리턴해야 하는 경우를 종종 만나게 됩니다.

예를 들면 두수를 전달받아 덧셈, 뺄셈, 곱셈, 나숫셈을 리턴 (4가지 값) 해주고 싶은 경우도 해당되겠지요.

C++ 11이 등장하기 전 여러 값을 함수에서 리턴하는 경우, 구조체 or 클래스 선언하고 값을 리턴해야 했습니다.

물론 동일한 타입의 여러값들을 리턴한다면 std::vector로 가능하지만 늘 타입들이 같은건 아닙니다.

 

C++ 11 이전

일반적으로 아래와 같은 방법으로 사용해 왔습니다.

4칙 연산의 결과를 저장할 구조체를 선언하고 이를 리턴하는 방식으로 말이죠.

#include <iostream>

struct RESULT
{
    double r1;
    double r2;
    double r3;
    double r4;
};

RESULT calc(double a, double b)
{
    RESULT result = {0,0,0,0};
    result.r1 = a + b;
    result.r2 = a - b;
    result.r3 = a * b;
    result.r4 = a / b;

    return result;
}

int main()
{
    double a = 5;
    double b = 2;
    
    RESULT result = calc(a, b);    
    std::cout << a << '+' << b << '=' << result.r1 << '\n';
    std::cout << a << '-' << b << '=' << result.r2 << '\n';
    std::cout << a << '*' << b << '=' << result.r3 << '\n';
    std::cout << a << '/' << b << '=' << result.r4 << '\n';
}

결과는 아래와 같습니다.

[코드 수행 결과]

 

C++ 11 이후

std::tuple 이라는 템플릿 클래스가 표준으로 등장합니다.

template <class... _Types>
class tuple;

이 클래스는 C++11의 중요한 특징 중 하나인 Variadic Template (가변인자 템플릿) 으로 구현되어 있습니다.

C++11 이전 템플릿은 가변인자를 처리하기 위해 템플릿 선언시 가변인자를 모두 명시해야 했지만, C++ 11 이후 Parameter pack(...) 이 등장하며 가변인자 템플릿 선언이 대폭 간소화 되었습니다.

 

여기까지만 배경을 소개하고 std::tuple을 어떻게 사용하지는 살펴보겠습니다.

#include <iostream>
#include <tuple>

std::tuple<double, double, double, double> calc(double a, double b)
{
	auto plus = a + b;
	auto minus = a - b;
	auto mul = a * b;
	auto div = a / b;

	return std::make_tuple(plus, minus, mul, div);
}

int main()
{
	double a = 5;
	double b = 2;

	// C++ 11
	auto result = calc(a, b);
	std::cout << "[C++ 11]" << '\n';
	std::cout << a << '+' << b << '=' << std::get<0>(result) << '\n';
	std::cout << a << '-' << b << '=' << std::get<1>(result) << '\n';
	std::cout << a << '*' << b << '=' << std::get<2>(result) << '\n';
	std::cout << a << '/' << b << '=' << std::get<3>(result) << '\n';

	std::cout << '\n';

	// C++ 17
	std::cout << "[C++ 17]" << '\n';
	auto [r1, r2, r3, r4] = calc(a, b);
	std::cout << a << '+' << b << '=' << r1 << '\n';
	std::cout << a << '-' << b << '=' << r2 << '\n';
	std::cout << a << '*' << b << '=' << r3 << '\n';
	std::cout << a << '/' << b << '=' << r4 << '\n';

} 

결과는 아래와 같습니다.

[코드 수행 결과]

먼저 tuple 헤더를 포함해야 합니다.

4칙 연산 결과를 리턴하는 calc() 함수의 리턴 타입을 아래와 같이 선언합니다.

std::tuple<double, doble, double, double>

calc() 함수에서 각 연산값을 변수에 저장하고 (plus, minus 등) std::make_tuple() 함수를 통해 tuple 객체를 생성하고 리턴합니다.

C++ 11의 경우, 20번 라인 auto 로 선언된 result 객체는 std::tuple<double...> 객체가 되며 값을 읽어올때는 std::get<인덱스> (튜플객체) 를 통해 값을 읽어올 수 있습니다.

  • std::get<0> (reuslt) 은 덧셈 결과 7
  • std::get<1> (reuslt) 은 뺄셈 결과 3
  • std::get<2> (reuslt) 은 곱셈 결과 10
  • std::get<3> (reuslt) 은 나눗셈 결과 2.5

 

C++ 17의 경우, 31번 라인 auto [변수, 변수, 변수, 변수] 방식으로 바로 변수에 담는 것도 가능하며, 언어 표준을 17로 변경해야 합니다.

[VS C++ 언어표준 설정]

std::tuple에 대한 보다 자세한 내용은 cppreference을 참조바랍니다.

이상으로 모든 설명을 마칩니다.

감사합니다.

댓글

이 블로그의 인기 게시물

Qt Designer 설치하기

PyQt5 기반 동영상 플레이어앱 만들기