2012-06-20 22 views
5

Có ai biết phương pháp sử dụng CRTP để đếm số lượng lớp con của một đối tượng không?Cách đếm số lượng lớp con CRTP của một lớp mẫu?

Giả sử chúng ta có một thiết lập tương tự như sau một:

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

const unsigned int ObjectSubClassCount = ...; 

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

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

và như vậy, như vậy mà, sử dụng TMP, chúng tôi có thể có một hằng số (ObjectSubClassCount) đại diện cho tổng số lớp con?

Có ai biết cách thực hiện việc này không?

Chỉnh sửa: Tôi muốn sử dụng kết quả như một tham số mẫu sau này, vì vậy tôi cần nó để được thực hiện với TMP ...

+0

Chỉ cần lưu ý, tôi đang nỗ lực giải quyết vấn đề này. Chỉ hỏi các bạn trong trường hợp tôi không bao giờ làm, hoặc bạn làm điều đó trước. – Serge

+0

Nên có thể - bạn có muốn có một bộ đếm cho các lớp con ở mọi cấp độ phân cấp hay chỉ toàn bộ số lớp con của đối tượng? – duselbaer

+0

Chỉ các lớp con ở cấp đó; Không mong đợi một chế độ thừa kế. – Serge

Trả lời

2

Nếu không có nhu cầu sử dụng kết quả như một tham số mẫu sau, tôi sẽ hãy thử làm như sau:

// 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); 

Chưa thử nhưng phải làm. Để có kết quả có sẵn như là một tham số mẫu một lần nữa (MPL) Tôi không có đủ kinh nghiệm trong MPL nhưng tôi nghi ngờ điều này là có thể.

0

Ok, vì vậy tôi đã có một câu trả lời ... có phần chấp nhận được. Tôi thấy rằng nó sẽ không hoạt động nếu các lớp con hoàn toàn không biết về eachother (ý tôi là, chúng ta đang nói một chút về lập trình hàm ...).

Đây là giải pháp cho việc này. Đó chắc chắn không phải là giải pháp tôi muốn; tuy nhiên, đó là một sự khởi đầu. Tôi đã buộc tất cả các đối tượng phải sử dụng một dạng CRTP, nhưng một đối tượng sử dụng nhiều định dạng danh sách được liên kết hơn. Bằng cách này, các lớp con của chúng ta phải được bắt nguồn từ một Object <> templated từ:

A: thân và B: gần đây nhất của lớp con được định nghĩa trước

đây là mã của tôi cho điều này (tôi sử dụng một mẫu từ <type_traits> một lần, chỉ cần lưu ý)

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 lớp trống cuối cùng này là lớp con mà chúng tôi đang đếm. Đây là tệp tiêu đề của chúng tôi. Trong tập tin cpp chính của chúng ta, chúng ta có:

int main() { 

std::cout << sub3::subclasscount; 

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

Chạy nó, chúng ta có được một kết quả đơn giản:

nào xác nhận rằng nó đã làm việc. Bây giờ, một số nhược điểm của giải pháp này là:

  • Chúng ta phải biết lớp con được xác định cuối cùng của chúng tôi là gì trước khi chúng tôi thêm vào.
  • Chúng ta phải theo kịp với bất cứ nơi nào chúng ta sử dụng bộ đếm lớp con, luôn luôn sửa đổi nó từ lớp con cuối cùng trong danh sách (điều này có thể được ngăn bằng cách sử dụng lớp con "endoflist" nhất định, cần được duy trì thay thế)

Mặt khác, mặc dù, bao gồm thực tế là chúng tôi không cần phải duy trì bất kỳ lớp con nào được xác định trước đây của chúng tôi.Tuy nhiên, tôi xem xét câu trả lời này nhiều hơn một "điểm khởi đầu" hơn là "giải pháp cuối cùng"; có lẽ cái gì đó có thể được mở rộng?

(còn, điều này có thể dễ dàng bị lạm dụng để thực hiện một hình thức cấu trúc cây, nơi subclasscount sẽ thực sự đại diện cho chiều sâu của bất kỳ nút được đưa ra trong cây)

Bất cứ ai có bất cứ ý tưởng từ đây?

Các vấn đề liên quan