2013-02-12 40 views
6

Tôi đang cố gắng để làm điều này:có điều kiện (SFINAE) override

struct A 
{ 
    virtual int f() const { return 0; } 
}; 

template <typename T> 
struct B : A 
{ 
    template <typename U = T, 
    typename std::enable_if<...some condition involving U...>::type> 
    int f() const { return 1; } 
}; 

Nên biết trước, tôi không thể kế thừa lớp mẫu (sử dụng ghi đè tĩnh). Đây là loại cấu trúc được phép và có thể thành viên mẫu B :: f() ghi đè lên thành viên A :: f()?

Trả lời

6

Hãy thử điều này:

template <typename T, typename=void> 
struct B : A 
{ 
    ... 
}; 

temlate <typename T> 
struct B<T, typename std::enable_if<...some condition...>::type>: 
    A 
{ 
    virtual int f() const override { return 1; } 
}; 

nơi chúng tôi có hai phiên bản của B<T>, một cho mà điều kiện là đúng (các enable_if một), một cho mà điều kiện là sai (mặc định một).

Nếu bạn muốn để có thể tái sử dụng thực hiện mặc định B của bạn, thậm chí bạn có thể làm điều này:

template <typename T, typename=void> 
struct B : A 
{ 
    ... 
}; 

template <typename T> 
struct B<T, typename std::enable_if<...some condition...>::type>: 
    B<T, bool> 
{ 
    virtual int f() const override { return 1; } 
}; 

nơi chúng tôi kế thừa từ các trường hợp "false" trong trường hợp "true". Nhưng đó là một chút bẩn với tôi - Tôi muốn đặt việc thực hiện phổ biến ở một số vị trí thứ ba (B_impl) chứ không phải là hack. (Điều đó cũng cho phép bạn xác nhận rằng đối số thứ hai là void trong trường hợp đầu tiên là B).

+0

ý tưởng tuyệt vời, hoạt động hoàn hảo. – user1095108