-
[C++ 14] 제네릭 프로그래밍 / 추가된 기능과 기억해야 할 내용프로그래밍 기초/C++ 2022. 5. 26. 11:00
제네릭 프로그래밍
함수 템플릿
타입 결정 방법
= 대부분의 경우 암묵적으로 잘 변환되나 int와 unsigned 같이 모호한 경우 명시적으로 결정해 줘야 한다.
template<typename TPara>
TPara max(TPara a, TPara b) { return a > b ? a : b; }
unsigned u1 = 2;
int i = 3;
max(u1, i); // 에러 발생!
max(int(u1), i); // Ok
max<int>(u1, i); // Ok
자동 리턴 타입
+ 컴파일러에서 리턴 타입도 추론이 가능하게 되었다.
template<typename T, typename U>
inline auto max(T a, U b)
{
return a > b ? a : b;}
네임 스페이스
네임 스페이스 한정
= 네임 스페이스로 특정 클래스, 변수 등을 선택해 사용할 수 있다.
struct same {};
namespace c1 {
struct same {};
namespace c2 {
struct same {};
struct csame {
::same x; // 전역 same
c1::same y; // c1의 same
same z; // c2의 same
}
}
}
= 네임 스페이스를 숨길 수 있다.
struct same {};
namespace c1 {
struct same {};
namespace c2 {
struct same {};
namespace c1{}
struct csame {
::same x; // 전역 same
c1::same y; // 에러 발생, c1이 c2 내부에 선언되었으나 내부의 c1에는 same이 없다.
same z; // c2의 same
}
}
}
클래스 템플릿
템플릿 매개변수
= 템플릿에 타입 외에 매개변수를 전달할 수 있다.
template<typename T, int Size>class fsize_vector{ using self = fsize_vector;public: using value_type = T;
const static int my_size = Size;
fsize_veoctor(int s = Size) { assert(s == Size); }
// ...
private:
T data[my_size];
}
fsize_vector<float, 3> v; // 크기가 3인 fsize_vector를 생성한다.
타입 추론과 정의
표현식의 타입
= 표현식을 추적하여 적절한 타입을 사용하도록 하는 decltype이 존재한다.
template<typename Vector1, typename Vector2>
auto operator+(const Vector1& v1, const Vector2& v2)
-> vector<decltype(v1[0] + v2[0])>; // v1[0] + v2[0]를 담을 수 있는 타입을 사용한다.
= 긴 표현식에 대해 간편하게 decltype을 사용할 수 있는 decltype(auto)가 존재한다.
decltype(f(g(x, y, z) + 3 * x)) a = f(g(x, y, z) + 3 * x); // 이러한 표현을
decltype(auto) b = f(g(x, y, z) + 3 * x); // 이와 같이 바꿀 수 있다.
람다
값에 의한 캡처
= 람다 스코프 외부의 변수나 상수를 값으로 참조할 수 있다. [=]으로 모든 변수를 값으로 참조할 수 있다.
double phi = 2.5;
auto sin_phi = [phi](double x) { return sin(phi * x); };
// 캡처해온 값은 람다 내부에서 수정이 불가능하며 수정하려면 mutable 키워드를 붙여줘야 한다.
double phi = 2.5;
auto sin_phi = [phi](double x) mutable { phi += 0.6; return phi; };
레퍼런스에 의한 캡처
= 람다 스코프 외부의 변수를 레퍼런스로 참조할 수 있다. [&]로 모든 변수를 레퍼런스로 참조할 수 있다.
double phi = 2.5;
auto pxr = [&phi](double x) { phi += x; };
pxr(1.0); // phi 는 3.5가 된다.
제네릭 람다
+ 람다의 인수 타입을 auto로 사용할 수 있게 되었다.
auto pxr = [&phi](auto x) { phi +=x; };