2013-05-18 36 views
5

bạn sẽ sử dụng cách so sánh thông số mẫu không loại trong một std::enable_if như thế nào? Tôi không thể tìm ra cách để làm điều này một lần nữa. (Tôi đã từng làm việc này, nhưng tôi đã bị mất mã vì vậy tôi không thể nhìn lại nó, và tôi không thể tìm thấy bài viết tôi tìm thấy câu trả lời trong cả hai.)std :: enable_if Với thông số mẫu không phải loại

Cảm ơn bạn đã giúp đỡ về chủ đề này.

template<int Width, int Height, typename T> 
class Matrix{ 
    static 
    typename std::enable_if<Width == Height, Matrix<Width, Height, T>>::type 
    Identity(){ 
     Matrix ret; 
     for (int y = 0; y < Width; y++){ 
      elements[y][y] = T(1); 
     } 
     return ret; 
    } 
} 

Edit: Cố định khung thiếu như đã chỉ ra trong ý kiến.

+3

Tôi có thể sử dụng 'static_assert' cho điều đó. Nó cung cấp thông báo lỗi rõ ràng. – chris

+0

'static_assert' thực sự là công cụ phù hợp:' std :: enable_if' là dành cho SFINAE và không có SFINAE có thể cho thành viên không phải mẫu của mẫu lớp. –

+0

Tôi đã nghĩ đến việc sử dụng 'static_assert', cuối cùng tôi có thể sử dụng nó. Nhưng tôi đã làm điều này trước khi làm việc, và với lợi thế của tự động hoàn thành thậm chí không liệt kê các chức năng cho ma trận không vuông ở nơi đầu tiên. Mặc dù vậy, tại thời điểm này, tôi đang cố gắng tìm ra cách mà tôi đã thực hiện điều này với đúng 'std :: enable_if'. – LostOfThought

Trả lời

3

Tất cả phụ thuộc vào loại lỗi/lỗi bạn muốn tăng trên mã không hợp lệ. Dưới đây là một khả năng (bỏ qua một bên rõ ràng các static_assert(Width==Height, "not square matrix");) (kiểu C++ 98)

#include<type_traits> 
template<int Width, int Height, typename T> 
class Matrix{ 
    public: 
    template<int WDummy = Width, int HDummy = Height> 
    static typename std::enable_if<WDummy == HDummy, Matrix<Width, Height, T> >::type 
    Identity(){ 
    Matrix ret; 
    for (int y = 0; y < Width; y++){ 
    // elements[y][y] = T(1); 
     } 
     return ret; 
    } 
}; 

int main(){ 
    Matrix<5,5,double> m55; 
    Matrix<4,5,double> m45; // ok 
    Matrix<5,5, double> id55 = Matrix<5,5, double>::Identity(); // ok 
// Matrix<4,5, double> id45 = Matrix<4,5, double>::Identity(); // compilation error! 
//  and nice error: "no matching function for call to ‘Matrix<4, 5, double>::Identity()" 
} 

EDIT: Trong C++ 11 mã có thể nhỏ gọn hơn và rõ ràng, (nó làm việc trong clang 3.2 nhưng không phải trong gcc 4.7.1, vì vậy tôi không chắc chắn như thế nào tiêu chuẩn đó là):

(C++ 11 phong cách)

template<int Width, int Height, typename T> 
class Matrix{ 
    public: 
     template<typename = typename std::enable_if<Width == Height>::type> 
     static Matrix<Width, Height, T> 
     Identity(){ 
     Matrix ret; 
     for (int y = 0; y < Width; y++){ 
     //  ret.elements[y][y] = T(1); 
     } 
     return ret; 
    } 
}; 
+0

Chỉ cần đánh tôi để hoàn thành câu trả lời của riêng tôi về câu hỏi. Cảm ơn câu trả lời bất kể. Được đánh dấu là đã được chấp nhận. – LostOfThought

+1

Trong C++ 11 có một lựa chọn nhỏ gọn hơn: 'template :: type> Nhận dạng ma trận tĩnh() {... } ' – alfC

+0

' WDummy' có cần thiết không? MSVC: CTP tháng 11 '12 với/W4 biên dịch tốt mà không có nó. – LostOfThought

1

Tôi đã tìm thấy câu trả lời cho câu hỏi của mình tại đây: Using C++11 std::enable_if to enable...

Trong giải pháp của tôi, SFINAE xảy ra trong kiểu trả lời mẫu của tôi, do đó làm cho mẫu chức năng có giá trị. Trong quá trình này, bản thân hàm cũng trở thành templated.

template<int Width, int Height, typename T> 
class Matrix{ 
    template<typename EnabledType = T> 
     static 
     typename Matrix<Width, Height, 
      typename std::enable_if<Width == Height, EnabledType>::type> 
     Identity(){ 
     Matrix ret; 
     for (int y = 0; y < Width; y++){ 
      ret.elements[y][y] = T(1); 
     } 
     return ret; 
    } 
} 
+0

Tôi đã thêm một phiên bản nhỏ gọn hơn câu trả lời của tôi, nhưng nó không hoạt động trong 'gcc'. BTW, 'typename' trước' Matrix' là tốt nhất dư thừa. – alfC

+0

Mã trong Chỉnh sửa của bạn giống như trong câu trả lời mới của tôi, không có điểm nào lặp lại nó ở đây. – alfC

+0

Tôi thấy điều đó ngay bây giờ. Không được dự định. Tôi đã rối tung với mã này cả đêm, tôi thực sự cảm thấy buồn chán. Bất kể, cảm ơn bạn đã giúp đỡ của bạn. – LostOfThought

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