[Modern C++] Type Deduction - decltype
Program Lang./C++ 2019. 7. 29. 15:351. decltype type deduction
decltype의 사용형식은 다음과 같다.
- decltype(expr) n
expr의 표현식의 따라서 type deduction은 크게 두가지로 분류될 수 있다.
- expr에 연산자가 존재하지 않을 경우의 type deduction
- expr에 연산자가 존재할 경우의 type deduction
2. expr에 연산자가 존재하지 않는 경우
expr에 연산자가 존재하지 않으면, expr과 동일한 type으로 변환된다.
1 2 3 4 5 6 | const int i = 0; decltype(i) n; // const int 과 동일 bool f( const Widget& w); decltype(w) n; // const Widget& 과 동일 decltype(f) n; // bool(const Widget&) 과 동일 |
3. expr에 연산자가 포함되어 있는 경우
expr에 연산자가 존재하면, expr이 lvalue냐 또는 rvalue냐를 식별해야 한다.
lvalue일 경우, reference가 붙지만 rvalue이면 reference는 붙이지 않는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int n = 10; int *p = &n; decltype(p) a; // no operation in expr, decltype(p)는 int* decltype(*p) a; // *p : lvalue, decltype(*p)는 int& int x[3] = {1, 2, 3} decltype(x[0]) a; // x[0] : lvalue, lvalue, decltype(x[0])는 int& vector< int > v {1, 2, 3}; decltype(v[0]) a; // v[0] : lvalue, lvalue, decltype(v[0])는 int& // rvalue case decltype(n + n) a; // n + n 는 rvalue, decltype(n + n)는 int decltype(n++) a; // n++ 는 rvalue, decltype(n++)는 int |
4. decltype(auto) 정리
c++14부터 지원하는 문법이다. 정확한 의미는 다음과 같다.
- auto
- type deduction이 필요하다.
- decltype
- type deduction rule은 decltype의 rule을 따른다.
결론적으로 type deduction을 수행해야 하는데, 이 때 decltype의 rule을 따른다의 의미이다.
이 형식이 어디에 사용되느냐는 함수의 return type과 관련이 있다.
Effective Modern C++의 추가 내용들은 perfact forwarding과 관련된 부분이 대부분이라서
간단히 왜 이런 구문이 나왔는지 측면에서 정리하고 넘어간다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | // c++11 코드 template < typename C, typename I> auto authAndAccess(C& c, I i) -> decltype(c[i]) { return c[i]; } // 위와 동일한 c++14 코드 template < typename C, typename I> auto authAndAccess(C& c, I i) { return c[i]; } |
위의 코드에서 함수의 return을 auto로 받고 있다. auto의 type deduction에서 기술하였듯이
함수의 return type의 auto의 경우 template의 type deduction 규칙을 따른다.
이 경우 return되는 c[i]는 C&이지만 auto의 type deduction이 template 규칙을 따르기 때문에
최종적으로 return type은 C가 된다.
이 경우 문제는 다음과 같은 코드에서 문제가 발생할 수 있다.
std::deque<int> d;
authAndAccess(d, 5) = 10;
authAndAccess()의 return type은 rvalue를 return하고 있어서 대입 시 에러가 발생한다.
여기서 해결책은 무엇인가? c++11의 경우에는 perfact forwarding에 대한 지식이 필요하므로
c++14 기준으로 해결책은 decltype(auto)로 return type을 바꾸는 것이다.
decltype(auto)의 의미에 따라서 C&로 return type이 결정된다.
1 2 3 4 5 6 | // authAndAccess의 return type을 C&로 받기 위한 해결책 template < typename C, typename I> decltype(auto) authAndAccess(C& c, I i) { return c[i]; } |
5. 정리
decltype의 type deduction은 expr의 표현식의 연산자 유무에 따라서 그 동작에 차이가 있다.
이 부분을 주의해서 사용하는 것이 핵심이고, decltype(auto)는 양념정도로 알아두면 좋을 듯 하다.
'Program Lang. > C++' 카테고리의 다른 글
[Modern C++] Summary of special member function generation (0) | 2019.09.20 |
---|---|
[Modern C++] reference collapsing (0) | 2019.07.31 |
[Modern C++] Type Deduction - auto (0) | 2019.07.29 |
[Modern C++] Type Deduction - Template (0) | 2019.07.28 |
[Basic] Object Generator (0) | 2017.07.09 |