프로그램/C,C++
[C++ 기본] 7. template function
naudhizb
2022. 1. 16. 00:02
반응형
// 7_함수템플릿1.cpp
#include <iostream>
//#include <stdio.h>
// cl /Tc 소스.cpp : C 언어
// cl /Tp 소스.cpp : C++ 언어
// 모든 타입에 동작하는 함수 만들기 - C언어
// 매크로 함수
//#define square(x) ((x)*(x))
// C++ : int 버전과 double 버전을 따로 만들자
// 방법 1. 사용자가 직접 만들자
// 방법 2. 함수 템플릿을 만들자. 컴파일러가 함수 생성
// Code Bloat : 템플릿 사용시 컴파일러가 너무 많은 함수(클래스)
// 를 만들어서 목적코드가 커지는 현상
template<typename T>
T square(T a)
{
// __FUNCTION__ : 함수 이름을 담은 C++ 표준 매크로.
// __FUNCSIG__ : 함수이름+signature. C++ 표준 아님.
// VC++ 만 지원
// __PRETTY_FUNCTION__ : g++에서 지원
std::cout << __FUNCSIG__ << std::endl;
return a * a;
}
int main()
{
square(3);
square(3.4);
short s = 3;
square(s);
int n = 3;
int ret = square(++n); // ((++n)*(++n))
printf("%d\n", ret);
//std::cout << ret << std::endl; // ??
}
잘 생각해보면 C언어에서도 template과 같은 기능을 수행한 적이 있을 것이다. 바로 define문을 이용한 macro function이다. 하지만, 매크로 함수 사용 시 가장 중요한 주의점이 바로 전처리기에 의한 효과가 어떻게 발현될지 모르는 문제였다. template function은 그러한 문제를 해결한다.
추가로 최신의 C표준, C++표준에서는 함수 이름을 매크로로 지원한다. 다만, 일부 기본정의 매크로의 경우 컴파일러마다 다르게 설정된다.
#include <iostream>
/*
int Add(int a, int b)
{
return a + b;
}
*/
/*
template<typename T>
T Add(T a, T b)
{
return a + b;
}
*/
/*
template<typename T1, typename T2>
T1 Add(T1 a, T2 b)
{
return a + b;
}
*/
// 반환타입 해결책1. 템플릿 인자로 타입을 전달 받는다.
template<typename R, typename T1, typename T2>
R Add(T1 a, T2 b)
{
return a + b;
}
int main()
{
//std::cout << Add<int, double>(1, 2.5 ) << std::endl;
std::cout << Add<double>(1, 2.5) << std::endl;
}
template 을 이용하여 함수 인자 뿐만 아니라 함수 반환타입 또한 정의할 수 있다. 그리고 template을 이용한 함수는 default 타입이 정의되어 있으므로 일부를 생략하여 사용할 수 있다.
// reference: https://blog.naver.com/wjdeh313/222618643998
#include <iostream>
// decltype(a+b) : a+b를 했을때 나오는 타입
// 실제로 더하기를 하는 것은 아님.
template<typename T1, typename T2>
//decltype(a+b) Add(T1 a, T2 b)
//auto Add(T1 a, T2 b)->decltype(a + b) // C++11 의 해결책
auto Add(T1 a, T2 b) // C++14. 함수 반환값으로 auto만 사용가능
{
return a + b ;
}
int main()
{
std::cout << Add(1, 3.4) << std::endl;
// a = 10; // error
// int a;
// a = 10; //ok
}
template function의 경우 위의 경우를 보면 알 수 있듯 반환 타입으로 auto를 설정한다. 하지만, 인자에 따른 적절한 타입을 반환하고 싶은 경우 decltype을 이용하여 타입을 설정할 수 있다. 하지만 decltype의 경우 컴파일 시간에 타입이 정해져야 하므로 경우에 따라 컴파일러가 오류를 발생시킬 수 있다. 이를 방지하기 위하여 template함수에 -> decltype(...)을 이용하여 템플릿 함수의 반환 타입인 auto에 대한 후행 반환타입(Trailing return type)을 정의할 수 있도록 C++11 표준에서 정의하고 있다.
반응형