6

CRTP を使用してオブジェクトのサブクラスの数をカウントする方法を知っている人はいますか?

次のような設定があるとします。

template <typename T>    
class Object
{
    ....  
};

const unsigned int ObjectSubClassCount = ...; 

class Subobject : public Object<SubObject>
{
    ....
};

class Second : public Object<Second>
{
    ....
};

など、TMP を使用すると、ObjectSubClassCountサブクラスの総数を表す定数 ( ) を取得できますか?

これを行う方法を知っている人はいますか?

編集:結果を後でテンプレートパラメータとして使用したいので、TMPで行う必要があります...

4

2 に答える 2

2

後で結果をテンプレートパラメータとして使用する必要がない場合は、次のように試してみます。

// Class which increments a given counter at instanciation
struct Increment {
  Increment(std::size_t& counter)
  {
    counter++;
  }
};

// This is your template base
template <typename T>    
class Object
{
  private:
    // For every instanciation of the template (which is done for a subclass)
    // the class counter should get incremented
    static Increment incrementCounter;
};

// This is the global object counter
static std::size_t classCounter;

// Static Member Variable
template<typename T>
Object<T>::incrementCounter(classCounter);

試したことはありませんが、試す必要があります。結果をテンプレートパラメータとして再び利用できるようにするには(MPL)MPLの経験が十分ではありませんが、これが可能かどうかは疑問です。

于 2012-06-20T06:59:14.787 に答える
0

わかりました、それで私は...いくぶん受け入れられる答えに出くわしました。サブクラスがお互いの知識をまったく持っていなければ、うまくいかないだろうと思いました(つまり、関数型プログラミングについて話しているのです...)。

これに対する解決策は次のとおりです。それは間違いなく私が望んでいた解決策ではありません。しかし、それは始まりです。すべてのオブジェクトにCRTPの形式を使用するように強制しましたが、リンクリスト形式をより多く使用するものです。このように、サブクラスは、以下からテンプレート化されたObject<>から派生する必要があります。

A:それ自体とB:以前に定義された最新のサブクラス

これが私のコードです(私は<type_traits>一度からテンプレートを使用します、ただのメモ)

template <typename T>   //SFINAE check for the existance of subclasscount static member
struct has_subclasscount
{

    template <typename U>
    static typename std::enable_if<sizeof(U::subclasscount) != 0, int>::type test(int);

    template <typename U>
    static char test(...);

    static const bool result = (sizeof(test<T>(0)) == sizeof(int))?(true):(false);
};


template <bool res, typename T>
struct return_subclasscount //the value to return is 0 if false
{
    static const int result = 0;
};


template <typename T>       
struct return_subclasscount<true, T>    //returns subclasscount only if the first parameter is true
{
    static const int result = T::subclasscount;
};


template <typename T>               //combines return_subclasscount and has_subclasscount
struct get_subclasscount
{
    static const int result = return_subclasscount<has_subclasscount<T>::result, T>::result;
};


template <typename This, typename Prev>
class Object
{
public:

    static const int subclasscount = 1 + get_subclasscount<Prev>::result;   //the subclass count
};


class sub1 : public Object<sub1, int>
{

};


class sub2 : public Object<sub2, sub1>
{

};


class sub3 : public Object<sub3, sub2>
{

};

これらの最後の3つの空のクラスは、カウントしているサブクラスです。これがヘッダーファイルです。メインの.cppファイルには、次のものがあります。

int main() {

std::cout << sub3::subclasscount;

char c;
std::cin >> c;
}

それを実行すると、次の単純な出力が得られます。

3

これは、それが機能したことを確認します。現在、このソリューションの欠点のいくつかは次のとおりです。

  • 追加する前に、最後に定義したサブクラスが何であるかを知る必要があります。
  • サブクラスカウンターを使用する場所についていく必要があり、常にリストの最後のサブクラスからのものになるように変更します(これは、一貫性のある「endoflist」サブクラスを使用することで回避できます。代わりに維持する必要があります)。

ただし、利点には、以前に定義したサブクラスを維持する必要がないという事実が含まれます。しかし、私はこの答えを「最終的な解決策」というよりも「出発点」だと考えています。おそらく拡張できる何か?

(また、これはツリー構造の形式を作成するために簡単に悪用される可能性があり、subclasscount実際にはツリー内の特定のノードの深さを表します)

誰かここから何かアイデアはありますか?

于 2012-06-20T08:16:54.143 に答える