#こんな状況に出くわした
複雑なテンプレートを書いているとこんな状況に出くわす
// 2つ以上のパラメータパックが欲しい!
template<typename... Components, typename... Events>
class ComponentManager
{
// ・・・
};
でもこれは当然コンパイルエラーになる
なぜならパラメータパックは最後の引数にしか使えないからだ
// できたとしても区切りがつかなくなる
ComponentManager<Component1, Component2, Event1, Event2> comp;
そこでタプル**std::tuple
**さんに活躍してもらうことにしましょう。1
#std::tupleを使ってパラメータパックをまとめる
std::tuple
を使うとこのようにまとめることができます。
// templateの中にタプル
using Components = ComponentManager<
std::tuple<
Component1,
Component2
>,
std::tuple<
Event1,
Event2
>
>;
それでは実装してみましょう。
少し不思議な書き方ですがとてもシンプルです。
template<typename Components, typename Events>
class ComponentManager;
template<typename... Components, typename... Events>
class ComponentManager<std::tuple<Components...>, std::tuple<Events...>>
{
// ・・・
}
ぜひ、試してみてください。
#応用
これを応用すればパラメータパックの2重ループが作れます
// 出力
template<typename Event, typename Component>
void PrintEventComponent()
{
std::cout << "Event:" << typeid(Event).name() << ", "
<< "Component: " << typeid(Component).name() << std::endl;
}
template<typename Components, typename Events>
class ComponentManager;
template<typename... Components, typename... Events>
class ComponentManager<std::tuple<Components...>, std::tuple<Events...>>
{
private:
// 内側のループ (Components)
template<typename Event>
static void InitializeEvent()
{
using accumulator_type = int[];
accumulator_type accumulator = { 0, (PrintEventComponent<Event, Components>(), 0)... };
(void)accumulator;
}
public:
// 外側のループ (Events)
static void InitializeEvents()
{
using accumulator_type = int[];
accumulator_type accumulator = { 0, (InitializeEvent<Events>(), 0)... };
(void)accumulator;
}
};
struct Component1 {};
struct Component2 {};
struct Event1 {};
struct Event2 {};
int main()
{
// usingを使えば何度も使うことができる
using Components = ComponentManager<std::tuple<Component1, Component2>, std::tuple<Event1, Event2>>;
Components::InitializeEvents();
return 0;
}
Event: struct Event1, Component: struct Component1
Event: struct Event1, Component: struct Component2
Event: struct Event2, Component: struct Component1
Event: struct Event2, Component: struct Component2
-
パラメータパックがまとめられるクラスなら何でもいいです。 ↩