2012-11-22 44 views
5

Hãy xem xét lớp mẫu theo cấp số nhân mượt mà bên dưới. Lớp này là để làm mịn/lọc dữ liệu tuần tự theo cấp số nhân (xem phương thức cập nhật). Elemtype có thể là một vector và Floattype thường là một vô hướng. Ví dụ.C++ kiểm tra ned typedef của tham số mẫu để lấy kiểu cơ sở vô hướng

ExponentialSmoother<Eigen::Vector2f, float> x(0.1, Vector2f(0.5, 0.5)); 

Trong ví dụ này các tham số mẫu thứ hai Floattype có thể tránh được vì lớp Matrix Eigen chứa một typedef lồng nhau để có được các loại cơ sở vô hướng:

Vector2f::Scalar 

Nó cũng là hợp lý để nhanh chóng cả Elemtype và Floatype làm nổi để làm mịn dữ liệu một chiều. Trong trường hợp này, tham số mẫu thứ hai cũng có thể bị bỏ qua.

template <class Elemtype, class Floattype> 
class ExponentialSmoother 
{ 
public: 
    // ctor 
    ExponentialSmoother(Floattype alpha, Elemtype& initial_estimate); 

    // getters 
    inline const Elemtype& getValue() const {return estimate_;} 
    inline const Floattype getAlpha() const {return alpha_;} 

    const Elemtype& update(const Elemtype& curr) 
    { 
     estimate_ = (alpha_ * curr) + (((Floattype)1-alpha) * estimate_); 
     return estimate_; 
    } 

private: 
    Elemtype estimate_; 
    Floattype alpha_; // smoothing factor within [0,1] 
} 

Bây giờ câu hỏi của tôi là giải pháp "thanh lịch nhất" để triển khai ExponentialSmoother chỉ với một tham số mẫu (loại phần tử) là gì? Nó sẽ hoạt động với các vectơ và ma trận Eigen mà còn với các kiểu dấu phẩy động.

Nói cách khác, có thể kiểm tra xem Elemtype :: Scalar tồn tại hay không (tức là Elemtype là float hoặc double) xác định Floattype là Elemtype?

Câu hỏi tương tự đã được hỏi here. Nhưng tôi tự hỏi những gì các giải pháp chung chung nhất là nếu ví dụ STL vectơ nên được hỗ trợ là tốt. Tất cả các kiểu có yêu cầu cùng một typedef lồng nhau (hoặc một số đặc điểm lớp có đặt tên nhất quán) không?

+0

* Tất cả các loại có yêu cầu cùng kiểu chữ lồng nhau (hoặc một số đặc điểm lớp có đặt tên nhất quán) không? * - Có. –

Trả lời

3

Bạn có thể sử dụng trình trợ giúp. Các liên kết mà bạn đã gần như chứa các giải pháp:

template<class T, class R = void> 
struct enable_if_type 
{ 
    typedef R type; 
}; 

template<class E, class Enable = void> 
struct GetFloatType 
{ 
    typedef E type; 
}; 

template<class E> 
struct GetFloatType<E, typename enable_if_type<typename E::Scalar>::type> 
{ 
    typedef typename E::Scalar type; 
}; 

Sau đó, trong lớp học của bạn:

template <class Elemtype, class Floattype = typename GetFloatType<Elemtype>::type> 
class ExponentialSmoother 
{ 
    // ... 
}; 

Ngoài ra, với những người dùng này vẫn có thể tự cung cấp loại phao của họ. Bạn có thể xem nó live. Tiền thưởng: hoạt động với C++ 03 mà không gặp vấn đề gì.

Lưu ý rằng bạn có thể thêm các chuyên môn một phần của GetFloatType. Here is a live example. Đừng quên rằng ElemType phải được chấp nhận cho chỉ một chuyên môn của GetFloatType, nếu không nó sẽ không rõ ràng (và gây ra lỗi trình biên dịch).

+0

Cảm ơn, đây thực sự là một giải pháp rất thanh lịch. Bây giờ nếu tôi muốn hỗ trợ các loại Ma trận khác, về cơ bản tôi có thể thêm các chuyên môn mẫu khác, ví dụ: 'mẫu struct GetFloatType :: type> {...} .' – spinxz

+0

Có, bạn có thể thêm các chuyên môn khác. Xem chỉnh sửa của tôi (kết thúc câu trả lời). – Synxis

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