반응형
Template Argument Type Deduction
- 컴파일러가 함수 인자를 보고 템플릿의 타입을 결정하는 것을 말한다.
- 함수 인자의 타입과 완전히 동일한 타입으로 결정되지는 않는다.
#include <iostream>
using namespace std;
// 함수 템플릿 인자가 값 타입(T a) 일때
template<typename T> void foo(T a)
{
++a;
}
int main()
{
int n = 0;
int& r = n;
const int c = n;
const int& cr = c;
foo(n); // T : int
foo(c); // T : const int ?
foo(r); // T : int& ?
foo(cr); // T : const int& ?
}
Template Argument Type Deduction 원리 1
- 템플릿 인자가 값 타입일때 (T a)
- 함수 인자가 가진 const, volatile, reference 속성을 제거하고 T의 타입을 결정한다.
- 주의 - 인자가 가진 const 속성만 제거 된다.
#include <iostream>
using namespace std;
// 함수 템플릿 인자가 값 타입(T a) 일때
template<typename T> void foo(T a)
{
}
int main()
{
int n = 0;
int& r = n;
const int c = n;
const int& cr = c;
foo(n); // T : int
foo(c); // T : int
foo(r); // T : int
foo(cr); // T : int
const char* s1 = "hello";
foo(s1); // T : char const* // s1이 아닌 char*가 const 이므로 제거 되지 않음
const char* const s2 = "hello";
foo(s2); // T : char const* // s2가 const 이므로 인자에 대한 const만 제거됨
}
Template Argument Type Deduction 원리 2
- 템플릿 인자가 참조 타입일때 (T& a)
- 함수 인자가 가진 reference 속성을 제거하고 T의 타입을 결정한다.
- const, volatile 속성은 유지한다.
#include <iostream>
using namespace std;
// 함수 템플릿 인자가 참조 타입(T& a) 일때
template<typename T> void foo(T& a)
{
++a;
}
int main()
{
int n = 0;
int& r = n;
const int c = n;
const int& cr = c;
foo(n); // T : int
foo(c); // T : const int
foo(r); // T : int
foo(cr); // T : const int
}
Template Argument Type Deduction 정리
- 템플릿 인자가 값 타입(T a)
- 함수 인자가 가진 const, volatile, reference 속성 제거 후 T 타입 결정
- 인자의 const 속성만 제거됨
- 템플릿 인자가 참조 타입(T& a)
- 함수 인자가 가진 reference 속성만 제거 후 T 타입 결정
- const, volatile 속성 유지
- 인자가 (const T& a)경우 const를 제거하고 T 타입 결정
- 템플릿 인자가 forwarding 레퍼런스 타입(T&& a)
- lvalue, rvalue 모두 전달 받음
- 템플릿 인자가 배열
- argument decay 발생
반응형
'프로그래밍 언어 > C++' 카테고리의 다른 글
C++ 템플릿 타입 추론(Argument Decay) (0) | 2019.07.14 |
---|---|
C++ 템플릿 타입 추론(배열의 주소) (0) | 2019.07.14 |
C++ 템플릿 타입 추론(std::typeid, boost::type_index 활용) (0) | 2019.07.14 |
C++ 비주얼스튜디오에서 boost 라이브러리 사용 방법 (0) | 2019.06.30 |
C++ 지연 인스턴스화(Lazy Instantiation) (0) | 2019.05.28 |