2012-06-20 51 views
5

有誰知道使用CRTP來計算一個對象的子類數量的方法嗎?如何計算模板類的CRTP子類的數量?

假設我們有以下一個類似的設置:

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

const unsigned int ObjectSubClassCount = ...; 

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

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

等,使得使用TMP,我們可能有一個常數(ObjectSubClassCount)表示子類的總數是多少?

有沒有人知道一種方法來做到這一點?

編輯:我想以後使用結果作爲模板參數,所以我需要它與TMP做...

+0

只是要注意,我正在努力解決這個問題,我自己。只要問你們,如果我從來不這樣做,或者你先做。 – Serge

+0

應該是可能的 - 你是否想要在每個層次級別都有一個子類的計數器,或者只有對象的子類的整數? – duselbaer

+0

只是在該級別的子類;不期待一個heirarchy。 – Serge

回答

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經驗,但我懷疑這是可能的。

0

好的,所以我找到了......可以接受的答案。 我覺得如果這個子類完全不瞭解彼此的知識(我的意思是說,我們正在談論某種函數式編程......),那麼它就行不通了。

這是一個解決方案。這絕對不是我想要的解決方案;但是,這是一個開始。我強迫所有對象使用一種形式的CRTP,但是它使用更多的鏈接列表格式。這樣一來,我們的子類必須從對象<導出>從模板:

答:本身 和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; 
} 

運行它,我們得到了一個簡單的輸出:

這證實它已經奏效。 現在,一些缺點這種解決方案是:

  • 我們必須知道我們最後定義的子類是,我們添加之前。
  • 我們必須跟上我們使用子類計數器的任何地方,並始終將其修改爲列表中的最後一個子類(這可以通過使用一個一致的「endoflist」子類來避免,而這需要維護)

但是,上行鏈路包含的事實是我們不需要維護我們之前定義的任何子類。但是,我認爲這個答案更多的是「起點」而不是「最終解決方案」。也許是可以擴展的東西?

(也,這很容易被濫用,使樹形結構,其中subclasscount實際上代表了樹中的任何給定節點的深度的一種形式)

任何人有任何想法從這裏?