프로그래밍 일반/C++ 프로그래밍

[C++] decltype 과 auto

지노윈 2020. 8. 17. 16:36
반응형

decltype은 주어진 식의 구체적인 타입 그대로 전달하는(추출하는) 키워드입니다.

decltype(expression)

 

auto는 상응하는 타입을 추론하는 키워드라면,

declytype은 상응하는 타입을 추출하는 키워드 입니다.

const int n = 1;
auto m = i;         // auto는 추론되며 int
decltype(i) k = i;  // decltype(i)는 추출되어 const int

decltype의 expression에 식별자(객체의 이름)가 아닌 expression이 온다면 어떻게 추출 되는지를 알아야 합니다.

이를 알기 위해서는 lvalue, prvalue, xvalue가 무엇인지 명확히 알아야 하며 Type Category를 참고해주세요.

[객체 지향 프로그래밍/C++ 프로그래밍] - C++ Type Category

 

식별자가 아닌 expression이라면 prvalue는 T, lvalue는 T&, xvalue는 T&&로 추출이 됩니다.

int a = 1;

decltype(a++) c;	// a++는 prvalue이며 int로 추론하여 추출
decltype(a+b) c;	// a+b는 prvalue이며 int로 추론하여 추출

decltype(++a) d;	// ++a는 lvalue이며 int&로 추론하여 추출
decltype((a)) d;	// (a)는 lvalue이며 int&로 추론하여 추출

decltype(std::move(a)) e;	// std::move(a)는 xvalue이며 int&&로 추론하여 추출

 

decltype의 쓰임에 대하여 좀더 자세히 살펴 보겠습니다.

C++11에서 다음의 코드를 컴파일하면 컴파일 오류가 발생합니다. (https://wandbox.org/에서 C++11)

#include <stdio.h>

template <typename T1, typename T2>
auto add(T1 t1, T2 t2){
  return t1 + t2;
}

int main()
{
    auto c = add<int, int>(1, 2);
    printf("c=%d\n", c);
}

C++11에서는 다음과 같이 trailling return type(후행 반환 형식)을 사용하여 다음과 같이 구현해주어야 합니다.

template <typename T1, typename T2>
auto add(T1 t1, T2 t2) -> decltype(t1 + t2) {
  return t1 + t2;
}

C++14(VS2015)부터는 auto 반환시 후행 반환 형식을 지정해주지 않아도 잘 동작합니다.

template <typename T1, typename T2>
auto add(T1 t1, T2 t2){
  return t1 + t2;
}

그렇지만 auto 타입은 템플릿 타입 추론에 의해서 결정이 되며 이 추론이 꾀 복잡하며 의도치 않은 추론이 될 수도 있습니다. 이를 방지하기 위해 decltype으로 auto를 감싸줄 필요가 있습니다.

template <typename T1, typename T2>
decltype(auto) add(T1 t1, T2 t2){
  return t1 + t2;
}