2012-06-15 38 views
6

Trong một mẫu, tôi muốn xem chi tiết tham số mẫu đối với loại không được tạo kiểu thực. Vì vậy:Các đặc điểm kiểu C++ để trích xuất lớp tham số mẫu

template <typename T> 
struct MyTemplate 
{ 
    // sadly there's no extract_Base 
    typedef typename extract_base<T>::MyType WorkType; 
}; 
struct X {}; 
template <typename T> struct Templ {}; 
//MyTemplate<Templ<X>>::WorkType is X; 
//MyTemplate<X>::WorkType is X; 

Giải pháp duy nhất tôi thấy là để xác định loại cơ sở thực như std :: vector <X> :: value_type là X. Nhưng tôi tò mò nếu có một cách để làm điều này mà không cần xác định các loại phụ trợ bên trong mỗi mẫu đích.

Tôi thấy thứ gì đó như http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html nhưng đây là bản nháp? và tôi không hiểu lắm.

Có tôi biết có nhiều thừa kế, nhưng ngay cả đối với trường hợp đơn giản, điều này sẽ rất tuyệt.

CẬP NHẬT: Giải pháp Nawaz phù hợp với tôi rất tốt và dễ dàng mở rộng đến các trường hợp cụ thể, ví dụ:

template<template<typename, typename> class X, typename T1, typename T2> 
struct extract_base <X<T1, T2>> //specialization 
{ 
    typedef T1 base; 
}; 

Tôi thậm chí có thể áp dụng is_base_of hoặc các bộ lọc khác cho T1/T2 v.v. Vì vậy, nó không hoạt động cho X < T, U > - ít nhất với g ++ 4.6.7.

+0

Điều này không liên quan gì đến lớp thừa kế hoặc cơ sở. –

+0

Có 'std :: is_base_of' nhưng có thể không phù hợp với mục đích của bạn. – dirkgently

Trả lời

7

Trước hết, hãy gọi nó là value_type thay vì base, vì value_type có vẻ là thuật ngữ thích hợp hơn để mô tả loại bạn muốn trích xuất.

Bạn có thể sử dụng này:

template<typename T> 
struct extract_value_type //lets call it extract_value_type 
{ 
    typedef T value_type; 
}; 

template<template<typename> class X, typename T> 
struct extract_value_type<X<T>> //specialization 
{ 
    typedef T value_type; 
}; 

Nó sẽ làm việc miễn là mẫu đối số để extract_value_type có dạng của một trong hai T hoặc X<T>. Tuy nhiên, nó sẽ không hoạt động cho X<T,U>. Nhưng sau đó nó rất dễ dàng để thực hiện nó trong C++ 11 bằng cách sử dụng mẫu variadic.

Sử dụng nó như:

template <typename T> 
struct MyTemplate 
{ 
    typedef typename extract_value_type<T>::value_type value_type; 
}; 

bản demo online: http://ideone.com/mbyvj


Bây giờ trong C++ 11, bạn có thể sử dụng mẫu variadic để làm extract_value_type làm việc với các lớp mẫu mà mất hơn một đối số mẫu, chẳng hạn như std::vector, std::set, std::list v.v.

template<template<typename, typename ...> class X, typename T, typename ...Args> 
struct extract_value_type<X<T, Args...>> //specialization 
{ 
    typedef T value_type; 
}; 

Bản trình diễn: http://ideone.com/SDEgq

+0

Biên dịch với "mẫu lớp X" và không hoạt động! Cảm ơn. – queen3

+0

@ queen3: Bây giờ hãy xem giải pháp variadic. – Nawaz

+0

Có, mặc dù X đã hoạt động đối với tôi, hãy xem cập nhật. Tuy nhiên đó là những gì tôi cần. – queen3

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