std::enable_if
- 스코프 지정 연산(::)에서 지정된 스코프 내에 존재하지 않는 타입을 사용한 경우를 활용하여 enable_if<true>::type은 존재하지만 enable_if<false>::type은 존재하지 않으므로 이를 바탕으로 특정한 경우에만 함수 템플릿을 사용할 수 있도록 만드는 것이다.
// STRUCT TEMPLATE enable_if
template <bool _Test, class _Ty = void>
struct enable_if {}; // no member "type" when !_Test
template <class _Ty>
struct enable_if<true, _Ty> { // type is _Ty for _Test
using type = _Ty;
};
std::is_base_of
- is_base_of 는 Template 첫번째 인자가 두번째 인자의 자식 객체이거나 동일한 객체일 경우 true를 반환해준다.
// STRUCT TEMPLATE is_base_of
template <class _Base, class _Derived>
struct is_base_of : bool_constant<__is_base_of(_Base, _Derived)> {
// determine whether _Base is a base of or the same as _Derived
};
Componet 구조에서의 활용
- Componet 구조에선 AddComponent를 통해 오브젝트에 Component를 추가할 경우 보통 Template를 통해 해당
객체를 Component로 업 캐스팅하여 Component List에 등록하는 형식이다.
문제는 원하는 Componet를 GetComponent 할때 인데, 어떤 Class가 들어오건 무조건 dynamic_cast를 통해 캐스팅이
되는지 매번 체크하는 것이 불합리 하다 생각하여 고안한 방법이다.
- 위의 두 Template를 이용하여 is_base_of 를 통해 현재 들어온 Class가 Component를 상속받고 있는지 체크하여
enable_if 의 bool 값으로 넣어주게되면 우리는 컴파일 되기 전에 해당 Class가 Component인지 아닌지 체크를 미리
할 수 있어 실수를 줄일 수 있다는 장점이 있다.
template <typename T, typename std::enable_if<std::is_base_of<Component, T>::value, bool>::type>
inline T* GameObject::AddComponent()
{
// 해당 컴포넌트 생성..
T* newCo = new T;
//Component* _newCo = decltype(T);
Component* _newCo = dynamic_cast<Component*>(newCo);
_newCo->SetGameObject(this);
_newCo->SetName<T>();
m_Components.insert(make_pair(type_index(typeid(T)), _newCo));
// 추가된 컴포넌트가 렌더러인지 체크 및 설정..
if (std::is_base_of<MeshRenderer, T>::value == true)
{
m_MeshType = eMeshType::NormalMesh;
}
if (std::is_base_of<SkinMeshRenderer, T>::value == true)
{
m_MeshType = eMeshType::SkinMesh;
}
if (std::is_base_of<CanvasRenderer, T>::value == true)
{
m_MeshType = eMeshType::Canvas;
}
return newCo;
}
'C++' 카테고리의 다른 글
[C++] Delegate & Function Pointer (0) | 2022.06.07 |
---|---|
[C++] Return Type Operator (0) | 2021.12.20 |
[C++] Define Macro (0) | 2021.12.19 |