프로그래밍 언어/C & C++ 정리

모던 C++ 함수형 프로그래밍 decltype

게임 개발 2023. 12. 16. 18:37
++

 이전의 C++과 비교하면 모던 C++에서는 어떤 것이 달라졌는지,
사실 많은 변화가 있었음은 알지만
그럼에도 불구하고 필자는 해당 기능들을 잘 알지 못한다.
때문에 게시글과 같이 성장하고자
매일 C++에 관련된 포스팅을 하고자 함을 기반으로
필자의 학습에 초점을 두어 작성되는
작성된 게시글이기에
독자 위주의 게시글이라기 보다는,
필자의 독서 기록용 게시글이 취지에 더욱 맞음을 인지해주고 읽어주길 바란다.

++

 

 

decltype 키워드로 표현식 타입 질의하기


 

 auto 키워드는 변수에 저장된 값이 어떤 타입인지 참고해 변수의 실제 타입을 지정할 수 있다.

또 반환하는 값의 타입을 보고 함수의 반환 타입 역시 추론이 가능하다.

auto 와 decltype 키워드를 조합해서 모던 C++을 좀 더 체계적으로 학습해보자.

 

우선 decltype이 언제 사용되는지부터 알아보자면, 이 키워드는 객체나 표현식의 타입을 알고 싶을 때 사용한다.

여러 줄에 걸쳐 함수나 변수 등을 선언하는 다음 코드를 보면 이해가 쉬워진다.

 

 

int main(void)
{

	const int func1();
	const int& func2();
	int i;

	struct X { double d; };
	const X* x = new X();

	// func1() 타입을 이용해서
	// const int 변수를 선언한다
	decltype(func1()) f1;

	// func2() 타입을 이용해서
	// const int& 변수를 선언한다
	decltype(func2()) f2 = NULL;
	 
	// i 타입을 사용해서
	// int 변수를 선언한다
	decltype(i) il;

	// struct X 타입을 사용해서
	// double 변수를 선언한다
	decltype(x->d) d1; // d1의 타입은 double 이다.
	decltype((x->d)) d2 = NULL; // d2의 타입은 const double&이다.

	return 0;
}

 

 

여기서 ((x->d) d2 가 왜 const double& 되는지 궁금할 것이다.

x->d는 x 인스턴스의 멤버 변수 d를 나타낸다.

따라서 decltype의 결과는 멤버 변수 d의 타입인 double이다.

반면에 (x0>d)는 표현식을 나타낸다.

특히 이 경우에는 표현식 주소를 얻을 수 있는 왼쪽(lvalue)이므로

decltype의 결과는 표현식의 주소 타입인 const double&이 된다.

 

 

이와 같이 어떤 객체 타입을 기반으로 다른 객체 타입을 지정할 수 있다.

앞에서 작성했던 add() 함수를 템플릿으로 바꿔보자.

만약 auto와 decltype을 사용할 수 없다면, 템플릿 코드는 다음과 같을 것이다.

 

template<typename I, typename J, typename K>
K add(I i, J j)
{
	return i + j;
}

 

 

auto는 후행 반환 타입을 사용해서 함수의 반환 타입을 지정할 수 있고,

decltype은 표현식을 참고해 타입을 추론할 수 있다.

따라서 다음과 같이 코드를 리팩토링 할 수 있다.

 

template<typename I, typename J>
auto add(I i, J j) -> decltype(i + j)
{
	return i + j;
}

 

 

제대로 동작하는지를 확인하기 위래서 다음 코드를 작성해서 실행해보면 

이 템플릿 코드는 두 개의 서로 다른 타입 int와 double을 더해서 결과를 출력한다.

 

template<typename I, typename J>
auto add(I i, J j) -> decltype(i + j)
{
	return i + j;
}

int main(void)
{
	std::cout << "[decltype]" << std::endl;

	// 템플릿 함수를 호출한다
	auto d = add<int, double>(2, 2.5);

	// 결과 출력
	std::cout << "result of 2 + 2.5 : " << d << std::endl;


	return 0;
}

 

 

 

이와 같이 auto와 decltype을 조합하면,

모던 C++을 응용하면 이전 버전의 C++의 방식으로 작성했던 것보다

더 간단한 방법으로 템플릿 코드를 작성할 수 있다.