次のコードを検討してください。
#include <iostream>
class Religion {
public:
virtual void pray() = 0;
};
// Example: Denomination<N0,N1,N2,N3> is derived from Denomination<N0,N1,N2> is derived
// from Denomination<N0,N1> is derived from Denomination<N0> is derived from Religion.
template <int...> class Denomination : public Religion {
virtual void pray() {std::cout << "Prays like a ... ?\n";}
};
template <> class Denomination<2> : public Religion {
virtual void pray() override {std::cout << "Prays like a Muslim.\n";}
};
template <> class Denomination<2,0> : public Denomination<2> {
virtual void pray() override {std::cout << "Prays like a Sunni Muslim.\n";}
};
template <> class Denomination<2,0,1> : public Denomination<2,5> {
virtual void pray() override {std::cout << "Prays like a Hanafi Sunni Muslim.\n";}
};
template <int...> struct D {};
class Person {
Religion* religion;
public:
template <int... Is>
Person (const D<Is...>&) : religion(new Denomination<Is...>) {}
// How to get the Flyweight Pattern here?
void pray() {religion->pray();}
};
int main() {
Person* person1 = new Person(D<2,0,1>{}); // "Prays like a Hanafi Sunni Muslim."
Person* person2 = new Person(D<2,0>{}); // "Prays like a Sunni Muslim."
Person* person3 = new Person(D<2>{}); // "Prays like a Muslim."
person1->pray();
person2->pray();
person3->pray();
Person* person4 = new Person(D<2,5,6,2,1,3>{});
person4->pray(); // Should be "Prays like a Hanafi Sunni Muslim."
}
だから私はPersonコンストラクタを
Person (const D<Is...>&) : religion(findDenomination<Is...>()) {}
staticReligion*の「テーブル」を検索します。結局のところ、まったく同じ宗派に属する 2 人は同じReligion*価値を共有する必要があります。これが、私がここで実装しようとしているフライ級デザイン パターンです。問題は、パックが長い間わからないことIs...です(サブサブ...デノミネーションの数はどこにも固定されていません)ので、単純な多次元配列は機能しません。代わりに、私がやっていることは、Religion*s のいくつかの静的 const ベクトルを適切なクラスに配置することであり、Is...パックはルックアップする最終的なベクトルを見つけるために使用されます。
更新:これを行うためのより良い方法はありますか? 以下に示すように、これまでに見つけたソリューションには大きな欠点があります。