📒 C++ - decltype
📌 decltype란?
- 표현식의 타입을 컴파일 시간에 추론할 수 있다.
- 주로 auto와 함께 사용된다.
#include <iostream>
int main()
{
decltype(1) num0 = 10;
decltype(num0) num1 = 20;
decltype(num1)& num2 = num1;
const decltype(num0) num3 = 10;
const decltype(num0)& num4 = num2;
decltype((num0)) num5 = num0;
decltype(1 + 22.f) num6 = 1.f;
int nums0[] = { 1,2,3 };
decltype(nums0) nums1 = { 1,2,3 };
}
- 위 예제는 decltype의 동작을 확인하기 위해 간단한 표현식을 사용하였지만, 실제에서는 타입이 변경될 가능성이 있을 때 사용하면 유용할 수 있다.
📌 decltype과 함수
#include <iostream>
using std::cout;
using std::endl;
int func(float)
{
cout << "func : ";
return 10;
}
int f(float)
{
cout << "f : ";
return 20;
}
int i = 0;
int& func0()
{
cout << "func0 : ";
return i;
}
struct Person
{
float weight;
float height;
};
int main()
{
decltype(func) f;
cout << "f : " << f(10.f) << endl;
decltype(func)& f0 = func;
cout << "f0 : " << f0(10.f) << endl;
decltype(func)* f1 = func;
cout << "f1 : " << f1(10.f) << endl;
decltype(func(1.f)) num7 = 20;
decltype(func0()) num8 = num7;
decltype(Person::weight) weight1;
}
Output:
f : f : 20
f0 : func : 10
f1 : func : 10
- 함수형 포인터 또는 레퍼런스로 형식 지정이 가능하다.
- 함수의 반환 값으로도 형식 지정이 가능하다.
#include <iostream>
struct Wrapper0
{
int value;
int getValue() const
{
return value;
}
};
struct Wrapper1
{
float value;
float& getValue()
{
return value;
}
};
template<typename T>
auto getValue(T& t)
{
return t.getValue();
}
int main()
{
Wrapper0 w0{ 0 };
Wrapper1 w1{ 1 };
getValue(w0);
getValue(w1) = 20.f;
}
- 레퍼런스를 auto로 추론 시, 값으로 받아들이기 때문에 수정이 불가하다.
#include <iostream>
struct Wrapper0
{
int value;
int getValue() const
{
return value;
}
};
struct Wrapper1
{
float value;
float& getValue()
{
return value;
}
};
template<typename T>
auto getValue(T& t) -> decltype(t.getValue())
{
return t.getValue();
}
int main()
{
Wrapper0 w0{ 0 };
Wrapper1 w1{ 1 };
getValue(w0);
getValue(w1) = 20.f;
std::cout << getValue(w0) << std::endl;
std::cout << getValue(w1) << std::endl;
}
Output:
0
20
- decltype은 레퍼런스도 추론 가능하기 때문에 레퍼런스를 리턴할 수 있게 된다.
- -> decltype(auto)를 사용해도 무방하다.