template<typename T>
T square(T a)
{
return a * a;
}
int main()
{
// square<int>(3);
// square를 쓰기전 까지는 기계어 코드가 생성이 안됨.
square(3);
// square를 쓰면 기계어 코드까지 생성이 된다.
// Template을 통해서 기계어를 뽑아 내는 과정을 Template Instantiation이라 한다.
}
- Template instantiation
- 컴파일러가 함수(클래스) 템플릿으로 부터 실제 함수(클래스)를 만들어 내는 과정
- 명시적/ 암시적 인스턴스화로 나눌 수 있다.
int add(int a, int b)
{
return a + b;
}
template<typename T>
T square(T a)
{
return a * a;
}
int main()
{
// square(3);
}
// 여기서 기계어를 뽑아보면
참고) 기계어 코드를 만드는 방법은
# 기계어 뽑는 방법
# VS기준으로
$ cl file.cpp /FAs
아래처럼 기계어가 add만 생성됨을 확인할 수 있다.
// ...
?add@@YAHHH@Z PROC ; add
; 2 : {
mov DWORD PTR [rsp+16], edx
mov DWORD PTR [rsp+8], ecx
; 3 : return a + b;
mov eax, DWORD PTR b$[rsp]
mov ecx, DWORD PTR a$[rsp]
add ecx, eax
mov eax, ecx
; 4 : }
ret 0
?add@@YAHHH@Z ENDP ; add
// ...
int add(int a, int b)
{
return a + b;
}
template<typename T>
T square(T a)
{
return a * a;
}
int main()
{
square(3);
}
square를 쓰게된다면 기계어에서 squre도 확인할 수 있다
// ...
PUBLIC ??$square@H@@YAHH@Z ; square<int>
pdata SEGMENT
$pdata$main DD imagerel $LN3
DD imagerel $LN3+21
DD imagerel $unwind$main
pdata ENDS
xdata SEGMENT
$unwind$main DD 010401H
DD 04204H
xdata ENDS
; Function compile flags: /Odtp
; File c:\users\ncsoft\test.cpp
; COMDAT ??$square@H@@YAHH@Z
_TEXT SEGMENT
a$ = 8
??$square@H@@YAHH@Z PROC ; square<int>, COMDAT
// ...
type deduction
template<typename T>
T square(T a)
{
return a * a;
}
int main()
{
square(3); // 클래스도 type deduction이 가능할까?
// 결론적으로 말하자면 C++17이전에는 불가능하다.
}
template<typename T>
class Vector
{
T* buff;
public:
Vector() {}
Vector(int sz, T initValue) {}
};
int main()
{
// Vector<int> v1(10, 3); // 10개를 3으로 초기화
// C++ 17부터는 아래가 가능
Vector v1(10, 3);
Vector v3; // 이게 될까 ??
// 안됨. -> 가이드를 줘야 된다.
}
template<typename T>
class Vector
{
T* buff;
public:
Vector() {}
Vector(int sz, T initValue) {}
};
// 가이드는 이렇게 주자.
Vector()->Vector<int>;
// Vector를 그냥 쓰면 int로 추론해 주세요.(C++17 기능)
int main()
{
Vector v3;
}
그래서 이게 뭐가 좋은데??
#include <list>
using namespace std;
int main()
{
// list<int> s = {1,2,3}; // 옛날 이야기
list s = {1,2,3}; // C++17 - okay
}
#include <list>
using namespace std;
template<typename T>
class Vector
{
T* buff;
public:
Vector() {}
Vector(int sz, T initValue) {}
template<typename C> Vector(C& c) {}
};
Vector()->Vector<int>;
Vector(C& c)->Vector<typename C::value_type>; // 생성자로 C가 들어오면 C의 value_type으로 추론해 주세요.
int main()
{
list s = {1,2,3};
Vector v3(s); // okay
}