++
이전의 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++의 방식으로 작성했던 것보다
더 간단한 방법으로 템플릿 코드를 작성할 수 있다.
'프로그래밍 언어 > C & C++ 정리' 카테고리의 다른 글
정적 멤버와 상수 멤버 (0) | 2024.02.05 |
---|---|
모던 C++ 함수형 프로그래밍 null 포인터 (0) | 2023.12.17 |
모던 C++ 함수형 프로그래밍 auto (0) | 2023.12.16 |
상황에 맞는 키워드 (Context-Sensitive Keywords) (0) | 2023.11.21 |
C++/ CX 와 C++/ CLI 의 차이 (0) | 2023.11.21 |