(회사에서 삽질하며 만든코드인데, 쓸일이 없어져서 폐기해버려서 슬쩍 포스팅 해본다.)
그러니까, 이런걸 만들고 싶은거였다.
타입리스트에 있는 항목들을 하나씩 인스턴스로 자동으로 생성하게 하기
어떤 오브젝트가 있고 이것은 다수의 모듈들의 상호작용으로 기능을 수행한다. 그런데 모듈들을 하나하나 enum화 하는것은 귀찮은 일이다.
그래서 모듈들을 타입리스트의 묶고 이 모듈 타입리스트에 있는 항목에 대해 하나씩 인스턴스를 생성하게 하고 싶다. 문제는, 타입리스트의 메타함수 결과값들은 컴파일 시점에 만들어지므로 for문을 돌며 인스턴스를 생성하는것이 불가능하다는것.
// 아래의 코드는 컴파일 되지 않는다.
for(int i = 0; i < TL::Length<T_TypeList>::value; ++i)
{
m_Modules[ i ] = new TL::TypeAt< T_TypeList, i>
}
이때 예전에 봐두었던 재미난 코드가 생각이 났다. Template Non-Type Parameter 밑에 있는, 재귀적 상속.
그렇다! N계층으로 재귀적으로 상속이 컴파일 인스턴스 되면, 생성자가 N번 불리므로, 원하는 작업을 할수 있다!
void InitContext()
{
// ...
m_pMockModuleGen = new T_MockModuleGen;
MakeUsingModule<
T_TypeList, TL::Length<T_TypeList>::value> makeIt(m_pMockModuleGen);
// ...
}
template<typename T_TypeList, int i>
struct MakeUsingModule : public MakeUsingModule<T_TypeList, i-1>
{
MakeUsingModule( MockModuleGenerator* pModuleGen)
: MakeUsingModule<T_TypeList, i-1>(pModuleGen)
{
pModuleGen->CreateUsingModule< TL::TypeAt<T_TypeList, i-1>::Result >();
}
};
template<typename T_TypeList>
struct MakeUsingModule<T_TypeList, 0>
{
MakeUsingModule(MockModuleGenerator* pModuleGen)
{
}
};
타입리스트에 대응하는 for문을 발견한 위대한(!) 순간이었다.