2016-08-22 13 views
8

Do là một lớp MyClass với thông số mẫuC++ lớp mẫu tham số phải có một lớp cha mẹ cụ

template<typename T> 
class MyClass 
{ 
    //... 
}; 

và một lớp MySecondClass với hai tham số mẫu.

template<typename T, typename U> 
class MySecondClass 
{ 
    //... 
}; 

Những gì tôi muốn làm là để hạn chế MyClass để chỉ cho phép một T đó là một loại hình xuất phát của MySecondClass. Tôi đã biết mình cần cái gì đó như

template<typename T, typename = std::enable_if<std::is_base_of<MySecondClass<?,?>, T>::value>> 
class MyClass 
{ 
    //... 
} 

Tôi chỉ không chắc chắn những gì để đưa vào cho ? như tôi muốn cho phép tất cả các khả năng MySecondClass 's.

+0

Tôi chỉnh sửa các câu hỏi. Nếu bạn cảm thấy rằng nó không chính xác xin vui lòng cuộn nó trở lại – NathanOliver

+0

Tôi tự hỏi về điểm của bài tập. Làm thế nào để bạn có kế hoạch để sử dụng thực tế là 'T' có nguồn gốc từ một số instantiation' MyParentClass'? Bạn tin rằng bạn có thể làm gì với 'T' biết điều này, rằng bạn không thể làm khác được? –

+2

tại sao bạn tiếp tục thay đổi câu hỏi? –

Trả lời

7

Bạn có thể sử dụng một tham số template mẫu cho mẫu cơ sở, sau đó kiểm tra xem một T* có thể được chuyển đổi sang một số Temp<Args...>:

template <template <typename...> class Of, typename T> 
struct is_base_instantiation_of { 
    template <typename... Args> 
    static std::true_type test (Of<Args...>*); 
    static std::false_type test (...); 

    using type = decltype(test(std::declval<T*>())); 
    static constexpr auto value = type::value; 
}; 

Live Demo

+0

Demo trực tiếp của bạn không biên dịch ... – Cornstalks

+3

@Cornstalks Tôi tin rằng đó là điểm như 'int 'không lấy được từ lớp mẫu' MyParentClass' (do đó 'enable_if_t' không thành công và đảm bảo' MyClass' không phải là một phần của độ phân giải quá tải cho 'MyClass '). – dfri

+0

@dfri: Ah, bạn nói đúng. Tôi hiểu sai nó. Một bình luận trên hai dòng chỉ ra rằng "biên dịch sẽ thất bại ở đây" sẽ giúp làm cho nó rõ ràng sự thất bại là cố ý. – Cornstalks

3

Bạn có thể sử dụng một đặc điểm tùy chỉnh để kiểm tra xem một loại có nguồn gốc từ một mẫu. Sau đó sử dụng đặc điểm này bên trong một static_assert:

#include <type_traits> 

template <template <typename...> class T, typename U> 
struct is_derived_from_template 
{ 
private: 
    template <typename... Args> 
    static decltype(static_cast<const T<Args...>&>(std::declval<U>()), std::true_type{}) test(
      const T<Args...>&); 
    static std::false_type test(...); 

public: 
    static constexpr bool value = decltype(test(std::declval<U>()))::value; 
}; 


template <typename T1, typename T2> 
struct MyParentClass 
{ 
}; 

template<typename T> 
struct MyClass 
{ 
    static_assert(is_derived_from_template<MyParentClass, T>::value, "T must derive from MyParentClass"); 
}; 


struct DerivedFromMyParentClass : MyParentClass<int, float>{}; 

struct Foo{}; 

int main() 
{ 
    MyClass<DerivedFromMyParentClass> m; 
    MyClass<Foo> f; 
} 

live example

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