SlideShare a Scribd company logo
1 of 41
Download to read offline
Template at C++
KPU
Lusain. Kim
Index What is a Template?
– Template
– Read Template
– using Template
 function template
 template class
 using by C++11
 Variadic Template
 SFINAE & Partial Template Specialization
– SFINAE
– Partial Template Specialization
– auto & decltype
– Example : FixValue
 Final Example : MFTE
– Example : MeasureFunctionTimeElapsed
What is a Template?
MSDN : https://msdn.microsoft.com/ko-kr/library/x5w1yety.aspx
TEMPLATE
 Template이 뭔가요?
– 확정되지 않은 무언가를 사용하여 실제 사용될 때까지 실제 형태를 만들지 않는 방법
– 템플릿에서의 무언가는 자료형 일 수도, 값일 수도 있음
 심지어 함수가 들어올 수도 있음
– 다른 언어에서 Generic Programming(일반적 프로그래밍) 라고 불림
4Present by Team Warp
TEMPLATE
 Template의 특징
– Template을 특수화Specialization 하지 않으면 컴파일 시 코드에 포함 안 됨
 특수화 : 무언가를 확정 시킴
 컴파일 되는 template 코드는 특수화된 코드
 template 코드 상태로 들어가는 것이 아님.
– Template은 컴파일 시점에서 확정되어야 함
 값으로 들어오는 Template은 컴파일 시점 상수
– Template은 한 번에 여러 개 사용 가능
 Template은 타입 또는 값에 대한 초기화를 할 수 있음
 함수와 동일하게, 오른쪽부터 채워 넣어야 함
 기본 타입 또는 값은 왼쪽의 Template 인수를 통하여 정할 수 있음
5Present by Team Warp
Read TEMPLATE
 Template을 읽는 방법 (함수 템플릿의 예)
template<typename Ty = int>
void Swap (Ty& lhs, Ty& rhs)
{
Ty temp = lhs;
lhs = rhs;
rhs = temp;
}
┌ Template을 사용하는데
─ 무슨 타입인지는 모르겠지만 그 타입의 이름은 Ty고
템플릿 인수를 생략하면 int로 간주하겠다.
• template<>에서, <> 안에 들어가는 자료형 또는 값은
템플릿 인수라고 한다.
• 자료형 인수는 typename 또는 class 를 앞에 붙여
타입 이름이라는 것을 나타낸다.
• typename 과 class 의 차이는 없다.
6Present by Team Warp
Read TEMPLATE
 Template을 읽는 방법 (함수 템플릿의 예)
int a = 10;
int b = 5;
Swap<int>(a, b); // a와 b로 Ty를 추론할 수 있으므로 <int> 생략 가능
┌ Swap의 첫 번째 템플릿 인수는 여기서 int로 하겠다.
• 템플릿 인수가 여러 개면 왼쪽부터
순서대로 입력한다.
• 호출 시 템플릿 인수를 명시하는 것을
명시적 템플릿 특수화라고 한다.
7Present by Team Warp
usE TEMPLATE
 Template의 사용처는 크게 2가지로 나눈다.
1. 함수 템플릿
– 함수에서 템플릿을 사용하는 것
– 클래스 내부에서도 함수 템플릿 구현 가능
– 호출 시 매개인자로 템플릿 인수 추론이 가능하면 템플릿 인수를 생략할 수 있음
ex】 std::swap(…); std::invoke(…); std::make_unique(…)
2. 템플릿 클래스
– 클래스에서 템플릿을 사용하는 것
– 반드시 템플릿 인수를 입력해야 함
– 템플릿 클래스의 포인터는 같은 템플릿 인수를 사용한 템플릿 클래스의 주소만 받음
ex】 std::vector<>
8Present by Team Warp
function TEMPLATE
 함수 템플릿은 언제 만들어요?
– 자료형이 무엇이든 함수 논리가 동일한 경우 = 범용적인 함수일 때
 Swap 함수의 경우
– 크기를 모르는 배열을 참조하고 싶을 때
template<typename Ty, int N>
constexpr int GetArraySize (Ty(&arr)[N]) noexcept { return N;}
9Present by Team Warp
function TEMPLATE
 함수 템플릿을 사용할 때 무엇을 주의해야 하나요?
– 무엇이든 템플릿 인수에 들어올 수 있지만 그것이 돌아간다고는 하지 않았다.
 다행히도 컴파일 에러를 뿜는다.
 하지만 에러 위치가 함수 호출 위치가 아니다
– 특정 자료형의 경우에 원하지 않은 결과가 도출될 수 있음
 무엇인지 모르는 자료형 Ty1과 0이 아닌 자료형 Ty2를 인자로 받을 때 Ty1 / Ty2 하는 함수
 12 / 5 의 결과로 2.4 를 받기를 원했지만 int / int 이기 때문에 결과는 2가 됨
 템플릿 부분 특수화를 통하여 해결 가능
– 멤버 함수 템플릿의 경우, 상속이 불가능
 자식 클래스에서 호출 가능
 자식 클래스에서 호출하는 멤버 함수는 overriding 적용됨
 반환형을 auto로 사용하면 함수 템플릿으로 판단
10Present by Team Warp
TEMPLATE class
 템플릿 클래스는 언제 만들어요?
– C++에서, class와 struct의 차이는 기본 접근자가 private/public 인가의 차이
– template class 라고 하지만 template struct 도 포함
– 클래스의 멤버 변수(field)를 범용적으로 받고 싶을 때
 자료구조에 유용, STL의 Container는 모두 class template
– 특정 조건에만 생성되게 하고 싶은 코드가 있을 때
 FixValue의 예에서 추가적인 설명
11Present by Team Warp
TEMPLATE class
 템플릿 클래스를 사용할 때 무엇을 주의해야 하나요?
– 템플릿 클래스는 템플릿 인수가 모두 같아야 동일한 타입이라고 판단
 해결방법 : 클래스 템플릿의 Base class 구현. 기능이 없어도 됨
– 템플릿 클래스를 상속한 자식 템플릿 클래스는 부모의 템플릿 인수도 알아야 함
 자료형 Ty를 템플릿 인수로 받는 부모 클래스를 상속할 경우
– Ty가 무슨 자료형 인지 직접 작성하거나
– 자식 클래스 역시 템플릿 클래스가 되어서 부모 클래스의 템플릿 인수를 자신도 받아야 함
– 함수 템플릿과 마찬가지로, 무엇이 들어올지 전혀 모르기 때문에 에러 발생 가능
12Present by Team Warp
using by C++11
MSDN : https://msdn.microsoft.com/ko-kr/library/dn467695.aspx
using
 C++11의 using에 대해 잠깐 짚고 넘어갑시다.
– C++11 부터 using 별칭 선언이 가능
– 기존에 typedef 를 사용하여 작성하던 별칭 선언을 using 키워드로도 되게 함
– 사용법 : using MyT = int;
– 장점 :
1. 가독성 향상
– 배열의 별칭 선언 (동일하게 크기 4인 int형 배열의 별칭 선언)
2. 템플릿 사용 가능
┌ 별칭
└ 별칭의 실체
14Present by Team Warp
typedef int int4[4];
using int4 = int[4];
using
 using template에 대해 조금 알아봅시다.
– 범용적인 별칭 선언이 가능
 예를 들어, 크기가 N인 배열을 만들고 싶을 경우(함수의 인자로 배열(의 시작주소)을 요구할 때)
template <typename Ty> using TyArr = Ty[];
– TyArr<int>{ 1, 2, 3, 4 }; 는 int arr[]{1,2,3,4}; 와 동일한 코드
– 예시 )
void SetColor4f(float* color); // color는 float[4]의 시작주소
…
SetColor4f( TyArr<float>{ 0.5f, 0.3f, 1.f, 1.f } );
 불필요한 변수를 만들지 않고 생성과 즉시 인자로 줄 수 있음
15Present by Team Warp
Variadic Template
MSDN : https://msdn.microsoft.com/ko-kr/library/dn439779.aspx
BLOG : http://lusain.egloos.com/3158201
variadic template
 가변 인자 템플릿이 뭐에요?
– C++11 부터 사용 가능
– 템플릿 인수의 개수가 고정되지 않은 템플릿 인수 묶음
 C의 printf 처럼 템플릿 인수를 가변적으로 넣을 수 있음
 가변 인자 템플릿은 하나의 템플릿 인수로 인식
 가변 인자 템플릿 타입의 템플릿 인수는 매개변수의 가장 오른쪽에만 가능
– 사용법 :
template<typename Fn, typename... Args>
void invokeFunc(Fn&& func , Args&&... args)
{
func(args...);
}
┌ typename... 으로 가변 인자 템플릿이라고 표시
└ 가변 인자 선언은 ...args 같이 인자 앞에 ...을 붙임
이 매개변수는 매개변수 팩이라고 부름
└ 가변 인자 사용은 args... 같이 인자 뒤에 ...을 붙임
args... 같은 표현을 팩 확장이라고 부름
17Present by Team Warp
variadic template
 가변 인자 템플릿은 어디에 사용해요?
– 가변인자는 다른 함수를 호출할 때의 매개인자 목록으로 사용 가능
void func(int a, int b, int c);
…
invokeFunc(func, 1, 2, 3); // 내부에서 func(1,2,3); 호출
– 가변인자와 템플릿 인수로 가변 인자 템플릿의 첫 번째 인자를 뺄 수 있음
template<typename Ty, typename... Args>
void print(Ty ty, Args... args)
{
printType(ty); // 가변 인자 템플릿의 첫 번째 인자 처리
print(args...);
}
가변 인자 템플릿의 첫 번째 인자 ┐ ┌ 첫 번째 인자를 제외한 가변 인자 템플릿
18Present by Team Warp
variadic template
 가변 인자 템플릿 오버로딩
– 가변인자가 하나도 남지 않게 될 경우를 위한 함수 오버로딩이 필요
void print(); // sizeof...(args) == 0 일 때
// 필요한 타입으로의 캐스팅
void printType(int i);
void printType(string s);
...
template<typename Ty, typename... Args>
void print(Ty ty, Args... args)
{
printType(ty); // 가변 인자 템플릿의 첫 번째 인자 처리
print(args...);
}
sizeof...(Args); 으로 매개변수 팩에 포함된
템플릿 인수 개수를 알 수 있다.
19Present by Team Warp
Substitution Failure Is Not An Error
Partial Template Specialization
MSDN : https://msdn.microsoft.com/ko-kr/library/3967w96f.aspx
GitHub: https://github.com/jwvg0425/ModernCppStudy/wiki/SFINAE
BLOG : http://lusain.egloos.com/3161710
20
SFINAE
 치환 실패는 오류가 아닙니다 Substitution Failure Is Not An Error?
– 템플릿 인수가 틀리더라도, 다른 템플릿에서 알맞은 치환이 있을 수 있음
 예를 들어, sum(Ty a, Ty b)에서, Ty에 Player 라는 class가 들어갈 수 있음
template<typename Ty> auto sum(Ty a, Ty b) { return {a + b}; }
 Player는 + 연산자 오버로딩이 되어있지 않음
 템플릿 인수가 Player 라면 sum은 정상적으로 동작하지 않음 = 컴파일 에러
21Present by Team Warp
SFINAE
 치환 실패는 오류가 아닙니다 Substitution Failure Is Not An Error?
 이 때, 다음과 같은 함수가 있다면 정상적으로 동작
( Player는 int id()라는 멤버함수를 가졌다고 가정 )
template<> auto sum(Player a, Player b) { return {a.id() + b.id()}; }
– 이렇게 일부 템플릿 인수를 확정시킨 것을 템플릿 부분 특수화라고 함
22Present by Team Warp
Partial Template Specialization
 템플릿 부분 특수화 Partial Template Specialization?
– 템플릿을 이용한 클래스, 함수 등에서 일부 템플릿을 특정하여 오버로드 하는 기법
template<typename Ty1,typename Ty2> auto sum(Ty1 a, Ty2 b);
이라는 함수가 있을 때,
template<typename Ty> auto sum(int a, Ty b);
template<typename Ty> auto sum(Ty a, int b);
같이 일부 템플릿을 특정(Ty1 또는 Ty2를 int)
23Present by Team Warp
AUTO & decltype
 쉬는 시간 : decltype이 뭐에요?
– decltype
 식을 decltype ( ) 키워드 안에 넣으면 식의 반환 타입을 추론하여 그 타입을 사용
 템플릿 프로그래밍에 유용하게 사용
 사용 예 :
int i = 10;
float f = 5.f;
decltype(i + f) p; // p의 type은 i + f와 동일한 타입. 즉 float
24Present by Team Warp
AUTO & decltype
 쉬는 시간 : auto가 뭐에요?
– auto
 C++11에서 바뀐 기능(이전까지는 지역 변수임을 명시하는 쓸모 없는 키워드였음)
– 크게 2가지의 사용처가 있으며, C++14에서 하나 더 추가됨
 변수로써 사용될 때
– 초기값이 반드시 존재해야 함
– 초기값의 타입을 알아서 잘 추론해서 타입을 컴파일 시점에 결정
 대체로 잘 추론하지만 가끔 원하지 않는 타입으로 추론할 때가 있기 때문에 사용에 주의
– 사용 예 :
int i = 5;
auto p = i; // p의 type은 int, 값은 5
25Present by Team Warp
AUTO & decltype
 쉬는 시간 : auto가 뭐에요?
– auto
 선언 시 초기화 값에서 const, volatile 등의 선언자가 모두 제거된 타입을 추론
 * 또는 & 등의 참조자를 붙일 수 있음. 이 경우에도 알아서 잘 추론해줌
 함수 포인터, lambda도 받을 수 있음
26Present by Team Warp
AUTO & decltype
 쉬는 시간 : auto가 뭐에요?
– auto
 함수의 반환형으로도 사용
– 반환 타입 확정을 decltype으로 컴파일 시점까지 지연하는 용도
 예:
template<class Ty1,class Ty2>
auto sum(Ty1 a, Ty2 b) -> decltype(a + b)
{
return a + b;
}
 C++14에서는 decltype을 굳이 적지 않고도 return 문에서 추론
27Present by Team Warp
└ Ty1과 Ty2의 + 연산자의 반환 타입이 무엇인지
모르기 때문에 a + b를 해본 뒤
그 결과값의 타입을 반환 타입으로 쓰겠다는 뜻
AUTO & decltype
 쉬는 시간 : auto가 뭐에요?
– auto
 C++14부터 lambda의 매개인자 타입으로도 사용 가능
 lambda는 템플릿 선언이 불가능했지만 auto 매개인자를 사용함으로써 템플릿 프로그래밍이 가능해짐
 사용 예:
auto p = [](auto a, auto b) { return a + b; };
…
p(10, 1.5f); // 11.5f 반환
28Present by Team Warp
example : FixValue
 FixValue : 정수를 받아 세 자리마다 쉼표(,)를 찍은 string 반환
– 함수 원본
– int 말고 다른 자료형도 받고 싶다!
– 그래, template을 써 보자!
string FixValue(int fixnum)
{
if (fixnum == 0) { return to_string(0); }
string szFix;
int count = 0;
while (fixnum > 0)
{
szFix += to_string(fixnum % 10);
if ((fixnum /= 10) == 0) continue;
if (++count % 4 != 3) continue;
szFix += ',';
++count;
}
reverse(szFix.begin(), szFix.end());
return szFix;
}
29Present by Team Warp
example : FixValue
 FixValue : 정수를 받아 세 자리마다 쉼표(,)를 찍은 string 반환
– template의 문제점이 떠오름
 엉뚱한 자료형이 올 수도 있음
– template을 포기할까?
template<typename Ty>
string FixValue(Ty fixnum)
{
if (fixnum == 0) { return to_string(0); }
string szFix;
int count = 0;
while (fixnum > 0)
{
szFix += to_string(fixnum % 10);
if ((fixnum /= 10) == 0) continue;
if (++count % 4 != 3) continue;
szFix += ',';
++count;
}
reverse(szFix.begin(), szFix.end());
return szFix;
}
30Present by Team Warp
example : FixValue
 FixValue : 정수를 받아 세 자리마다 쉼표(,)를 찍은 string 반환
– 템플릿 부분 특수화를 이용해보자!
– SFixValue
 선언으로 두 번째 인자의 기본값 결정
 두 번째 인자로 정수 타입인지 확인
 두 번째 인자에 따라 호출이 결정
– true일 때 정상 호출
– false일 때 에러 출력
template<typename Ty,
bool isInteger = std::is_integral<Ty>::value>
struct SFixValue;
template<typename Ty>
struct SFixValue<Ty, true>
{
template<typename Ty>
static string _Call(Ty fixnum) { ... } //진짜
}
template<typename Ty>
struct SFixValue<Ty, false>
{
template<typename Ty>
static string _Call(Ty fixnum) { ... } //Error
};
31Present by Team Warp
example : FixValue
 FixValue : 정수를 받아 세 자리마다 쉼표(,)를 찍은 string 반환
– 함수 호출은 이렇게
– 함수 호출 시 컴파일 타임에 추론
– fixnum이 정수 형이면 함수 호출 성공
– 그 이외일 경우 : struct SFixValue<Ty, false> 에서 정의한 _Call 함수 호출
 실패 시 코드 :
template<typename Ty>
inline string FixValue(Ty fixnum)
{
return SFixValue<Ty>::_Call(fixnum);
}
template<typename Ty> struct SFixValue<Ty, false>
{
template<typename Ty> static string _Call(Ty fixnum)
{
static_assert(false, "FixValue only use integer type!");
return string();
}
};
32Present by Team Warp
type traits
 std::is_integral<Ty>::value 가 도대체 무슨 코드에요?
– C++11에서 형식 인수의 속성에 대한 정보를 제공하거나 변형된 형식을 생성하는
컴파일 타임 상수를 제공하는 템플릿을 정의하기 위한 헤더 제공
 #include <type_traits>
 템플릿 인수에 대해 컴파일 타임에 사용 가능한 상수를 반환
 is_integral<Ty>의 경우, Ty가 정수 형인지 질의하는 구조체
– ::value로 컴파일 시점에 상수 bool 값을 반환
ex】is_void, is_base_of, is_integral… 등
33Present by Team Warp
Final Example
Measure Function Time Elapsed
example : Measure Fn Time Elapsed
– 함수의 실행시간을 측정하는 함수 구현이 목표
– 실행시간을 가공하는 함수, 측정 함수, 측정 함수의 인자(가변)를 매개인자로 받음
– 측정 함수의 반환값이 존재하면 MFTE가 반환하는 것으로 설계
– 실제 사용 예 :
bool CScene::Render(HDC hDC) { ... }
…
bool bRenderSucc = MeasureFunctionTimeElapsed(
[&](auto d) {
auto du = chrono::duration_cast<chrono::nanoseconds>(d).count();
MessageBox(nullptr, to_wstring(du).c_str(), "", MB_OK);
}
, &CScene::Render, hDC);
35Present by Team Warp
가공함수는 모든 함수마다
다르므로 람다로 구현 ──
┌Render의 반환값을 MFTE가 대신 받음
└Render 함수와 매개인자. 클래스 멤버 함수도 쓸 수 있다.
• 필요한 헤더
#include <chrono>
#include <type_traits>
example : Measure Fn Time Elapsed
– 함수 구현
– 현재 시간을 기록하고 함수를 실행한 뒤 경과시간을 체크하는 방식
– 반환값을 저장하기 위해 auto retval 을 사용하여 함수 반환값을 저장 후 반환
– 근데 void 형은 auto로 못 받는데?
36Present by Team Warp
template<class _Callable, class _OutputFn, class... _Types>
static auto _Call(_Callable&& _Obj, _OutputFn&& _Out, _Types&&... _Args)
{
auto startTime = std::chrono::high_resolution_clock::now();
auto retval = std::invoke(
std::forward<_Callable>(_Obj), std::forward<_Types>(_Args)...);
auto du = std::chrono::high_resolution_clock::now() - (startTime);
std::invoke(std::forward<_OutputFn>(_Out), du);
return retval;
}
└ 보라색 배경색이 칠해진 부분은 시간 측정과 처리 부분
example : Measure Fn Time Elapsed
– 함수 구현
– 템플릿 부분 특수화로 void 반환형 용 함수를 만들자!
37Present by Team Warp
template<class _Callable, class _OutputFn, class... _Types>
static auto _Call(_Callable&& _Obj, _OutputFn&& _Out, _Types&&... _Args)
{
auto startTime = std::chrono::high_resolution_clock::now();
std::invoke(std::forward<_Callable>(_Obj), std::forward<_Types>(_Args)...);
auto du = std::chrono::high_resolution_clock::now() - (startTime);
std::invoke(std::forward<_OutputFn>(_Out), du);
}
└ 보라색 배경색이 칠해진 부분은 시간 측정과 처리 부분
example : Measure Fn Time Elapsed
– 템플릿 부분 특수화
38Present by Team Warp
template<
typename returnType
, bool _Is_void = is_void<returnType>::value
>
struct InvokerMeasureFunc;
template<typename Ty>
struct InvokerMeasureFunc<Ty, true>
: function_invoke_no_return_for_measure_time_elapsed { };
template<typename Ty>
struct InvokerMeasureFunc<Ty, false>
: function_invoke_return_late_for_measure_time_elapsed { };
┌void 반환 함수에 대한 MFTE를 가진 구조체
┌void 이외의 반환 함수에 대한 MFTE를 가진 구조체
└ 반환형이 void 인지 판단하는 형식 특질(type traits)
example : Measure Fn Time Elapsed
– 함수 본문
39Present by Team Warp
template<typename FnOutput, typename FnFunc, typename... Args> inline
constexpr auto MeasureFunctionTimeElapsed(FnOutput&& outputFunc, FnFunc&& Function,
Args&&... args) noexcept
{
return (InvokerMeasureFunc<decltype(std::invoke(std::forward<FnFunc>(Function)
, std::forward<Args>(args)...) )>
::_Call( std::forward<FnFunc>(Function),
std::forward<FnOutput>(outputFunc), std::forward<Args>(args)...)
);
}
┌갈색 배경색이 칠해진 부분은 함수의 returnType을
구하기 위한 부분
Q & A
E-Mail : sain9212@gmail.com
Twitter : @Lusain_Kim
Thank You!

More Related Content

What's hot

C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2Chris Ohk
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1Chris Ohk
 
C++20 Key Features Summary
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features SummaryChris Ohk
 
[C++ korea] effective modern c++ study item8~10 정은식
[C++ korea] effective modern c++ study item8~10 정은식[C++ korea] effective modern c++ study item8~10 정은식
[C++ korea] effective modern c++ study item8~10 정은식은식 정
 
[C++ Korea] Effective Modern C++ Study, Item 1 - 3
[C++ Korea] Effective Modern C++ Study, Item 1 - 3[C++ Korea] Effective Modern C++ Study, Item 1 - 3
[C++ Korea] Effective Modern C++ Study, Item 1 - 3Chris Ohk
 
[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...
[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...
[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...Seok-joon Yun
 
[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...
[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...
[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...Seok-joon Yun
 
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준Seok-joon Yun
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
C++ Advanced 강의 1주차
C++ Advanced 강의 1주차C++ Advanced 강의 1주차
C++ Advanced 강의 1주차HyunJoon Park
 
[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features SummaryChris Ohk
 
Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리ssuser7c5a40
 
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌Seok-joon Yun
 
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...Seok-joon Yun
 
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기Chris Ohk
 
C++ Advanced 강의 4주차
 C++ Advanced 강의 4주차 C++ Advanced 강의 4주차
C++ Advanced 강의 4주차HyunJoon Park
 
C++ 타입 추론
C++ 타입 추론C++ 타입 추론
C++ 타입 추론Huey Park
 
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...Seok-joon Yun
 

What's hot (20)

C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1
 
C++20 Key Features Summary
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features Summary
 
[C++ korea] effective modern c++ study item8~10 정은식
[C++ korea] effective modern c++ study item8~10 정은식[C++ korea] effective modern c++ study item8~10 정은식
[C++ korea] effective modern c++ study item8~10 정은식
 
[C++ Korea] Effective Modern C++ Study, Item 1 - 3
[C++ Korea] Effective Modern C++ Study, Item 1 - 3[C++ Korea] Effective Modern C++ Study, Item 1 - 3
[C++ Korea] Effective Modern C++ Study, Item 1 - 3
 
[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...
[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...
[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...
 
[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...
[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...
[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...
 
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
C++ Advanced 강의 1주차
C++ Advanced 강의 1주차C++ Advanced 강의 1주차
C++ Advanced 강의 1주차
 
C++11
C++11C++11
C++11
 
[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary
 
Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리
 
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
 
C++11
C++11C++11
C++11
 
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
 
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
 
C++ Advanced 강의 4주차
 C++ Advanced 강의 4주차 C++ Advanced 강의 4주차
C++ Advanced 강의 4주차
 
C++ 타입 추론
C++ 타입 추론C++ 타입 추론
C++ 타입 추론
 
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
 

Similar to Template at c++

Effective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshinEffective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshinDong Chan Shin
 
Effective c++ 4
Effective c++ 4Effective c++ 4
Effective c++ 4현찬 양
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)익성 조
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 pptInjae Lee
 
[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿해강
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부quxn6
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
[0820 석재호]headfirst디자인패턴
[0820 석재호]headfirst디자인패턴[0820 석재호]headfirst디자인패턴
[0820 석재호]headfirst디자인패턴Jaeho Seok
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10흥배 최
 
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++Min-soo Park
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4성연 김
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.Ryan Park
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2성연 김
 
Data Structure 4
Data Structure 4Data Structure 4
Data Structure 4yonsei
 
JMI Techtalk: 강재욱 - Toward tf.keras from tf.estimator - From TensorFlow 2.0 p...
JMI Techtalk: 강재욱 - Toward tf.keras from tf.estimator - From TensorFlow 2.0 p...JMI Techtalk: 강재욱 - Toward tf.keras from tf.estimator - From TensorFlow 2.0 p...
JMI Techtalk: 강재욱 - Toward tf.keras from tf.estimator - From TensorFlow 2.0 p...Lablup Inc.
 
[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩jusingame
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven DevelopmentChangHyeon Bae
 
Effective c++ chapter 7,8
Effective c++ chapter 7,8Effective c++ chapter 7,8
Effective c++ chapter 7,8문익 장
 

Similar to Template at c++ (20)

Effective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshinEffective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshin
 
Effective c++ 4
Effective c++ 4Effective c++ 4
Effective c++ 4
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 ppt
 
[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
[0820 석재호]headfirst디자인패턴
[0820 석재호]headfirst디자인패턴[0820 석재호]headfirst디자인패턴
[0820 석재호]headfirst디자인패턴
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
 
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2
 
EC 789
EC 789EC 789
EC 789
 
Data Structure 4
Data Structure 4Data Structure 4
Data Structure 4
 
JMI Techtalk: 강재욱 - Toward tf.keras from tf.estimator - From TensorFlow 2.0 p...
JMI Techtalk: 강재욱 - Toward tf.keras from tf.estimator - From TensorFlow 2.0 p...JMI Techtalk: 강재욱 - Toward tf.keras from tf.estimator - From TensorFlow 2.0 p...
JMI Techtalk: 강재욱 - Toward tf.keras from tf.estimator - From TensorFlow 2.0 p...
 
[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
 
Effective c++ chapter 7,8
Effective c++ chapter 7,8Effective c++ chapter 7,8
Effective c++ chapter 7,8
 
7 8 1
7 8 17 8 1
7 8 1
 

Template at c++

  • 2. Index What is a Template? – Template – Read Template – using Template  function template  template class  using by C++11  Variadic Template  SFINAE & Partial Template Specialization – SFINAE – Partial Template Specialization – auto & decltype – Example : FixValue  Final Example : MFTE – Example : MeasureFunctionTimeElapsed
  • 3. What is a Template? MSDN : https://msdn.microsoft.com/ko-kr/library/x5w1yety.aspx
  • 4. TEMPLATE  Template이 뭔가요? – 확정되지 않은 무언가를 사용하여 실제 사용될 때까지 실제 형태를 만들지 않는 방법 – 템플릿에서의 무언가는 자료형 일 수도, 값일 수도 있음  심지어 함수가 들어올 수도 있음 – 다른 언어에서 Generic Programming(일반적 프로그래밍) 라고 불림 4Present by Team Warp
  • 5. TEMPLATE  Template의 특징 – Template을 특수화Specialization 하지 않으면 컴파일 시 코드에 포함 안 됨  특수화 : 무언가를 확정 시킴  컴파일 되는 template 코드는 특수화된 코드  template 코드 상태로 들어가는 것이 아님. – Template은 컴파일 시점에서 확정되어야 함  값으로 들어오는 Template은 컴파일 시점 상수 – Template은 한 번에 여러 개 사용 가능  Template은 타입 또는 값에 대한 초기화를 할 수 있음  함수와 동일하게, 오른쪽부터 채워 넣어야 함  기본 타입 또는 값은 왼쪽의 Template 인수를 통하여 정할 수 있음 5Present by Team Warp
  • 6. Read TEMPLATE  Template을 읽는 방법 (함수 템플릿의 예) template<typename Ty = int> void Swap (Ty& lhs, Ty& rhs) { Ty temp = lhs; lhs = rhs; rhs = temp; } ┌ Template을 사용하는데 ─ 무슨 타입인지는 모르겠지만 그 타입의 이름은 Ty고 템플릿 인수를 생략하면 int로 간주하겠다. • template<>에서, <> 안에 들어가는 자료형 또는 값은 템플릿 인수라고 한다. • 자료형 인수는 typename 또는 class 를 앞에 붙여 타입 이름이라는 것을 나타낸다. • typename 과 class 의 차이는 없다. 6Present by Team Warp
  • 7. Read TEMPLATE  Template을 읽는 방법 (함수 템플릿의 예) int a = 10; int b = 5; Swap<int>(a, b); // a와 b로 Ty를 추론할 수 있으므로 <int> 생략 가능 ┌ Swap의 첫 번째 템플릿 인수는 여기서 int로 하겠다. • 템플릿 인수가 여러 개면 왼쪽부터 순서대로 입력한다. • 호출 시 템플릿 인수를 명시하는 것을 명시적 템플릿 특수화라고 한다. 7Present by Team Warp
  • 8. usE TEMPLATE  Template의 사용처는 크게 2가지로 나눈다. 1. 함수 템플릿 – 함수에서 템플릿을 사용하는 것 – 클래스 내부에서도 함수 템플릿 구현 가능 – 호출 시 매개인자로 템플릿 인수 추론이 가능하면 템플릿 인수를 생략할 수 있음 ex】 std::swap(…); std::invoke(…); std::make_unique(…) 2. 템플릿 클래스 – 클래스에서 템플릿을 사용하는 것 – 반드시 템플릿 인수를 입력해야 함 – 템플릿 클래스의 포인터는 같은 템플릿 인수를 사용한 템플릿 클래스의 주소만 받음 ex】 std::vector<> 8Present by Team Warp
  • 9. function TEMPLATE  함수 템플릿은 언제 만들어요? – 자료형이 무엇이든 함수 논리가 동일한 경우 = 범용적인 함수일 때  Swap 함수의 경우 – 크기를 모르는 배열을 참조하고 싶을 때 template<typename Ty, int N> constexpr int GetArraySize (Ty(&arr)[N]) noexcept { return N;} 9Present by Team Warp
  • 10. function TEMPLATE  함수 템플릿을 사용할 때 무엇을 주의해야 하나요? – 무엇이든 템플릿 인수에 들어올 수 있지만 그것이 돌아간다고는 하지 않았다.  다행히도 컴파일 에러를 뿜는다.  하지만 에러 위치가 함수 호출 위치가 아니다 – 특정 자료형의 경우에 원하지 않은 결과가 도출될 수 있음  무엇인지 모르는 자료형 Ty1과 0이 아닌 자료형 Ty2를 인자로 받을 때 Ty1 / Ty2 하는 함수  12 / 5 의 결과로 2.4 를 받기를 원했지만 int / int 이기 때문에 결과는 2가 됨  템플릿 부분 특수화를 통하여 해결 가능 – 멤버 함수 템플릿의 경우, 상속이 불가능  자식 클래스에서 호출 가능  자식 클래스에서 호출하는 멤버 함수는 overriding 적용됨  반환형을 auto로 사용하면 함수 템플릿으로 판단 10Present by Team Warp
  • 11. TEMPLATE class  템플릿 클래스는 언제 만들어요? – C++에서, class와 struct의 차이는 기본 접근자가 private/public 인가의 차이 – template class 라고 하지만 template struct 도 포함 – 클래스의 멤버 변수(field)를 범용적으로 받고 싶을 때  자료구조에 유용, STL의 Container는 모두 class template – 특정 조건에만 생성되게 하고 싶은 코드가 있을 때  FixValue의 예에서 추가적인 설명 11Present by Team Warp
  • 12. TEMPLATE class  템플릿 클래스를 사용할 때 무엇을 주의해야 하나요? – 템플릿 클래스는 템플릿 인수가 모두 같아야 동일한 타입이라고 판단  해결방법 : 클래스 템플릿의 Base class 구현. 기능이 없어도 됨 – 템플릿 클래스를 상속한 자식 템플릿 클래스는 부모의 템플릿 인수도 알아야 함  자료형 Ty를 템플릿 인수로 받는 부모 클래스를 상속할 경우 – Ty가 무슨 자료형 인지 직접 작성하거나 – 자식 클래스 역시 템플릿 클래스가 되어서 부모 클래스의 템플릿 인수를 자신도 받아야 함 – 함수 템플릿과 마찬가지로, 무엇이 들어올지 전혀 모르기 때문에 에러 발생 가능 12Present by Team Warp
  • 13. using by C++11 MSDN : https://msdn.microsoft.com/ko-kr/library/dn467695.aspx
  • 14. using  C++11의 using에 대해 잠깐 짚고 넘어갑시다. – C++11 부터 using 별칭 선언이 가능 – 기존에 typedef 를 사용하여 작성하던 별칭 선언을 using 키워드로도 되게 함 – 사용법 : using MyT = int; – 장점 : 1. 가독성 향상 – 배열의 별칭 선언 (동일하게 크기 4인 int형 배열의 별칭 선언) 2. 템플릿 사용 가능 ┌ 별칭 └ 별칭의 실체 14Present by Team Warp typedef int int4[4]; using int4 = int[4];
  • 15. using  using template에 대해 조금 알아봅시다. – 범용적인 별칭 선언이 가능  예를 들어, 크기가 N인 배열을 만들고 싶을 경우(함수의 인자로 배열(의 시작주소)을 요구할 때) template <typename Ty> using TyArr = Ty[]; – TyArr<int>{ 1, 2, 3, 4 }; 는 int arr[]{1,2,3,4}; 와 동일한 코드 – 예시 ) void SetColor4f(float* color); // color는 float[4]의 시작주소 … SetColor4f( TyArr<float>{ 0.5f, 0.3f, 1.f, 1.f } );  불필요한 변수를 만들지 않고 생성과 즉시 인자로 줄 수 있음 15Present by Team Warp
  • 16. Variadic Template MSDN : https://msdn.microsoft.com/ko-kr/library/dn439779.aspx BLOG : http://lusain.egloos.com/3158201
  • 17. variadic template  가변 인자 템플릿이 뭐에요? – C++11 부터 사용 가능 – 템플릿 인수의 개수가 고정되지 않은 템플릿 인수 묶음  C의 printf 처럼 템플릿 인수를 가변적으로 넣을 수 있음  가변 인자 템플릿은 하나의 템플릿 인수로 인식  가변 인자 템플릿 타입의 템플릿 인수는 매개변수의 가장 오른쪽에만 가능 – 사용법 : template<typename Fn, typename... Args> void invokeFunc(Fn&& func , Args&&... args) { func(args...); } ┌ typename... 으로 가변 인자 템플릿이라고 표시 └ 가변 인자 선언은 ...args 같이 인자 앞에 ...을 붙임 이 매개변수는 매개변수 팩이라고 부름 └ 가변 인자 사용은 args... 같이 인자 뒤에 ...을 붙임 args... 같은 표현을 팩 확장이라고 부름 17Present by Team Warp
  • 18. variadic template  가변 인자 템플릿은 어디에 사용해요? – 가변인자는 다른 함수를 호출할 때의 매개인자 목록으로 사용 가능 void func(int a, int b, int c); … invokeFunc(func, 1, 2, 3); // 내부에서 func(1,2,3); 호출 – 가변인자와 템플릿 인수로 가변 인자 템플릿의 첫 번째 인자를 뺄 수 있음 template<typename Ty, typename... Args> void print(Ty ty, Args... args) { printType(ty); // 가변 인자 템플릿의 첫 번째 인자 처리 print(args...); } 가변 인자 템플릿의 첫 번째 인자 ┐ ┌ 첫 번째 인자를 제외한 가변 인자 템플릿 18Present by Team Warp
  • 19. variadic template  가변 인자 템플릿 오버로딩 – 가변인자가 하나도 남지 않게 될 경우를 위한 함수 오버로딩이 필요 void print(); // sizeof...(args) == 0 일 때 // 필요한 타입으로의 캐스팅 void printType(int i); void printType(string s); ... template<typename Ty, typename... Args> void print(Ty ty, Args... args) { printType(ty); // 가변 인자 템플릿의 첫 번째 인자 처리 print(args...); } sizeof...(Args); 으로 매개변수 팩에 포함된 템플릿 인수 개수를 알 수 있다. 19Present by Team Warp
  • 20. Substitution Failure Is Not An Error Partial Template Specialization MSDN : https://msdn.microsoft.com/ko-kr/library/3967w96f.aspx GitHub: https://github.com/jwvg0425/ModernCppStudy/wiki/SFINAE BLOG : http://lusain.egloos.com/3161710 20
  • 21. SFINAE  치환 실패는 오류가 아닙니다 Substitution Failure Is Not An Error? – 템플릿 인수가 틀리더라도, 다른 템플릿에서 알맞은 치환이 있을 수 있음  예를 들어, sum(Ty a, Ty b)에서, Ty에 Player 라는 class가 들어갈 수 있음 template<typename Ty> auto sum(Ty a, Ty b) { return {a + b}; }  Player는 + 연산자 오버로딩이 되어있지 않음  템플릿 인수가 Player 라면 sum은 정상적으로 동작하지 않음 = 컴파일 에러 21Present by Team Warp
  • 22. SFINAE  치환 실패는 오류가 아닙니다 Substitution Failure Is Not An Error?  이 때, 다음과 같은 함수가 있다면 정상적으로 동작 ( Player는 int id()라는 멤버함수를 가졌다고 가정 ) template<> auto sum(Player a, Player b) { return {a.id() + b.id()}; } – 이렇게 일부 템플릿 인수를 확정시킨 것을 템플릿 부분 특수화라고 함 22Present by Team Warp
  • 23. Partial Template Specialization  템플릿 부분 특수화 Partial Template Specialization? – 템플릿을 이용한 클래스, 함수 등에서 일부 템플릿을 특정하여 오버로드 하는 기법 template<typename Ty1,typename Ty2> auto sum(Ty1 a, Ty2 b); 이라는 함수가 있을 때, template<typename Ty> auto sum(int a, Ty b); template<typename Ty> auto sum(Ty a, int b); 같이 일부 템플릿을 특정(Ty1 또는 Ty2를 int) 23Present by Team Warp
  • 24. AUTO & decltype  쉬는 시간 : decltype이 뭐에요? – decltype  식을 decltype ( ) 키워드 안에 넣으면 식의 반환 타입을 추론하여 그 타입을 사용  템플릿 프로그래밍에 유용하게 사용  사용 예 : int i = 10; float f = 5.f; decltype(i + f) p; // p의 type은 i + f와 동일한 타입. 즉 float 24Present by Team Warp
  • 25. AUTO & decltype  쉬는 시간 : auto가 뭐에요? – auto  C++11에서 바뀐 기능(이전까지는 지역 변수임을 명시하는 쓸모 없는 키워드였음) – 크게 2가지의 사용처가 있으며, C++14에서 하나 더 추가됨  변수로써 사용될 때 – 초기값이 반드시 존재해야 함 – 초기값의 타입을 알아서 잘 추론해서 타입을 컴파일 시점에 결정  대체로 잘 추론하지만 가끔 원하지 않는 타입으로 추론할 때가 있기 때문에 사용에 주의 – 사용 예 : int i = 5; auto p = i; // p의 type은 int, 값은 5 25Present by Team Warp
  • 26. AUTO & decltype  쉬는 시간 : auto가 뭐에요? – auto  선언 시 초기화 값에서 const, volatile 등의 선언자가 모두 제거된 타입을 추론  * 또는 & 등의 참조자를 붙일 수 있음. 이 경우에도 알아서 잘 추론해줌  함수 포인터, lambda도 받을 수 있음 26Present by Team Warp
  • 27. AUTO & decltype  쉬는 시간 : auto가 뭐에요? – auto  함수의 반환형으로도 사용 – 반환 타입 확정을 decltype으로 컴파일 시점까지 지연하는 용도  예: template<class Ty1,class Ty2> auto sum(Ty1 a, Ty2 b) -> decltype(a + b) { return a + b; }  C++14에서는 decltype을 굳이 적지 않고도 return 문에서 추론 27Present by Team Warp └ Ty1과 Ty2의 + 연산자의 반환 타입이 무엇인지 모르기 때문에 a + b를 해본 뒤 그 결과값의 타입을 반환 타입으로 쓰겠다는 뜻
  • 28. AUTO & decltype  쉬는 시간 : auto가 뭐에요? – auto  C++14부터 lambda의 매개인자 타입으로도 사용 가능  lambda는 템플릿 선언이 불가능했지만 auto 매개인자를 사용함으로써 템플릿 프로그래밍이 가능해짐  사용 예: auto p = [](auto a, auto b) { return a + b; }; … p(10, 1.5f); // 11.5f 반환 28Present by Team Warp
  • 29. example : FixValue  FixValue : 정수를 받아 세 자리마다 쉼표(,)를 찍은 string 반환 – 함수 원본 – int 말고 다른 자료형도 받고 싶다! – 그래, template을 써 보자! string FixValue(int fixnum) { if (fixnum == 0) { return to_string(0); } string szFix; int count = 0; while (fixnum > 0) { szFix += to_string(fixnum % 10); if ((fixnum /= 10) == 0) continue; if (++count % 4 != 3) continue; szFix += ','; ++count; } reverse(szFix.begin(), szFix.end()); return szFix; } 29Present by Team Warp
  • 30. example : FixValue  FixValue : 정수를 받아 세 자리마다 쉼표(,)를 찍은 string 반환 – template의 문제점이 떠오름  엉뚱한 자료형이 올 수도 있음 – template을 포기할까? template<typename Ty> string FixValue(Ty fixnum) { if (fixnum == 0) { return to_string(0); } string szFix; int count = 0; while (fixnum > 0) { szFix += to_string(fixnum % 10); if ((fixnum /= 10) == 0) continue; if (++count % 4 != 3) continue; szFix += ','; ++count; } reverse(szFix.begin(), szFix.end()); return szFix; } 30Present by Team Warp
  • 31. example : FixValue  FixValue : 정수를 받아 세 자리마다 쉼표(,)를 찍은 string 반환 – 템플릿 부분 특수화를 이용해보자! – SFixValue  선언으로 두 번째 인자의 기본값 결정  두 번째 인자로 정수 타입인지 확인  두 번째 인자에 따라 호출이 결정 – true일 때 정상 호출 – false일 때 에러 출력 template<typename Ty, bool isInteger = std::is_integral<Ty>::value> struct SFixValue; template<typename Ty> struct SFixValue<Ty, true> { template<typename Ty> static string _Call(Ty fixnum) { ... } //진짜 } template<typename Ty> struct SFixValue<Ty, false> { template<typename Ty> static string _Call(Ty fixnum) { ... } //Error }; 31Present by Team Warp
  • 32. example : FixValue  FixValue : 정수를 받아 세 자리마다 쉼표(,)를 찍은 string 반환 – 함수 호출은 이렇게 – 함수 호출 시 컴파일 타임에 추론 – fixnum이 정수 형이면 함수 호출 성공 – 그 이외일 경우 : struct SFixValue<Ty, false> 에서 정의한 _Call 함수 호출  실패 시 코드 : template<typename Ty> inline string FixValue(Ty fixnum) { return SFixValue<Ty>::_Call(fixnum); } template<typename Ty> struct SFixValue<Ty, false> { template<typename Ty> static string _Call(Ty fixnum) { static_assert(false, "FixValue only use integer type!"); return string(); } }; 32Present by Team Warp
  • 33. type traits  std::is_integral<Ty>::value 가 도대체 무슨 코드에요? – C++11에서 형식 인수의 속성에 대한 정보를 제공하거나 변형된 형식을 생성하는 컴파일 타임 상수를 제공하는 템플릿을 정의하기 위한 헤더 제공  #include <type_traits>  템플릿 인수에 대해 컴파일 타임에 사용 가능한 상수를 반환  is_integral<Ty>의 경우, Ty가 정수 형인지 질의하는 구조체 – ::value로 컴파일 시점에 상수 bool 값을 반환 ex】is_void, is_base_of, is_integral… 등 33Present by Team Warp
  • 35. example : Measure Fn Time Elapsed – 함수의 실행시간을 측정하는 함수 구현이 목표 – 실행시간을 가공하는 함수, 측정 함수, 측정 함수의 인자(가변)를 매개인자로 받음 – 측정 함수의 반환값이 존재하면 MFTE가 반환하는 것으로 설계 – 실제 사용 예 : bool CScene::Render(HDC hDC) { ... } … bool bRenderSucc = MeasureFunctionTimeElapsed( [&](auto d) { auto du = chrono::duration_cast<chrono::nanoseconds>(d).count(); MessageBox(nullptr, to_wstring(du).c_str(), "", MB_OK); } , &CScene::Render, hDC); 35Present by Team Warp 가공함수는 모든 함수마다 다르므로 람다로 구현 ── ┌Render의 반환값을 MFTE가 대신 받음 └Render 함수와 매개인자. 클래스 멤버 함수도 쓸 수 있다. • 필요한 헤더 #include <chrono> #include <type_traits>
  • 36. example : Measure Fn Time Elapsed – 함수 구현 – 현재 시간을 기록하고 함수를 실행한 뒤 경과시간을 체크하는 방식 – 반환값을 저장하기 위해 auto retval 을 사용하여 함수 반환값을 저장 후 반환 – 근데 void 형은 auto로 못 받는데? 36Present by Team Warp template<class _Callable, class _OutputFn, class... _Types> static auto _Call(_Callable&& _Obj, _OutputFn&& _Out, _Types&&... _Args) { auto startTime = std::chrono::high_resolution_clock::now(); auto retval = std::invoke( std::forward<_Callable>(_Obj), std::forward<_Types>(_Args)...); auto du = std::chrono::high_resolution_clock::now() - (startTime); std::invoke(std::forward<_OutputFn>(_Out), du); return retval; } └ 보라색 배경색이 칠해진 부분은 시간 측정과 처리 부분
  • 37. example : Measure Fn Time Elapsed – 함수 구현 – 템플릿 부분 특수화로 void 반환형 용 함수를 만들자! 37Present by Team Warp template<class _Callable, class _OutputFn, class... _Types> static auto _Call(_Callable&& _Obj, _OutputFn&& _Out, _Types&&... _Args) { auto startTime = std::chrono::high_resolution_clock::now(); std::invoke(std::forward<_Callable>(_Obj), std::forward<_Types>(_Args)...); auto du = std::chrono::high_resolution_clock::now() - (startTime); std::invoke(std::forward<_OutputFn>(_Out), du); } └ 보라색 배경색이 칠해진 부분은 시간 측정과 처리 부분
  • 38. example : Measure Fn Time Elapsed – 템플릿 부분 특수화 38Present by Team Warp template< typename returnType , bool _Is_void = is_void<returnType>::value > struct InvokerMeasureFunc; template<typename Ty> struct InvokerMeasureFunc<Ty, true> : function_invoke_no_return_for_measure_time_elapsed { }; template<typename Ty> struct InvokerMeasureFunc<Ty, false> : function_invoke_return_late_for_measure_time_elapsed { }; ┌void 반환 함수에 대한 MFTE를 가진 구조체 ┌void 이외의 반환 함수에 대한 MFTE를 가진 구조체 └ 반환형이 void 인지 판단하는 형식 특질(type traits)
  • 39. example : Measure Fn Time Elapsed – 함수 본문 39Present by Team Warp template<typename FnOutput, typename FnFunc, typename... Args> inline constexpr auto MeasureFunctionTimeElapsed(FnOutput&& outputFunc, FnFunc&& Function, Args&&... args) noexcept { return (InvokerMeasureFunc<decltype(std::invoke(std::forward<FnFunc>(Function) , std::forward<Args>(args)...) )> ::_Call( std::forward<FnFunc>(Function), std::forward<FnOutput>(outputFunc), std::forward<Args>(args)...) ); } ┌갈색 배경색이 칠해진 부분은 함수의 returnType을 구하기 위한 부분
  • 40. Q & A E-Mail : sain9212@gmail.com Twitter : @Lusain_Kim