2010-05-12 4 views
5

Tôi có một ma trận lớp templated. Tôi muốn chuyên một hàm cho kiểu phức tạp, trong đó T có thể là bất cứ thứ gì. Tôi đã thử điều này:Chuyên môn của một thành viên của một lớp mẫu cho một tham số lớp mẫu kiểu

6 template <typename T> 
    7 class Matrix { 
    8  public : 
    9    static void f(); 
10 };   
11 template<typename T> void Matrix<T>::f() { cout << "generic" << endl; } 
12 template<> void Matrix<double>::f() { cout << "double" << endl; } 
13 template<typename T> void Matrix<std::complex<T> >::f() { cout << "complex" << endl; } 

Dòng 13 không biên dịch. Làm thế nào tôi có thể làm điều đó ?

+1

bản sao có thể có của [Chuyên viên tạo mẫu lớp] (http://stackoverflow.com/questions/2672536/specializing-a-class-template-constructor) –

+0

Tôi không thấy làm thế nào đây là một số .. –

+0

Anh ấy đang cố gắng chuyên chức năng thành viên không phải mẫu. Tương tự trong câu hỏi đó. –

Trả lời

1

Thực tế, tôi đã tìm thấy một cách thông minh để thực hiện thông qua Boost. Vì tôi không muốn thư viện của tôi phụ thuộc vào Boost, đây là mã:

template <class T, T val> struct integral_constant 
{ 
     typedef integral_constant<T, val> type; 
     typedef T value_type; 
     static const T value = val; 
};  
typedef integral_constant<bool, true> true_type; 
typedef integral_constant<bool, false> false_type; 
template <typename T> struct is_complex : false_type{}; 
template <typename T> struct is_complex<std::complex<T> > : true_type{}; 

template <typename T> 
class Matrix { 
     public : 
      static void f() { f_(typename is_complex<T>::type()); } 
     private : 
      static void f_(true_type) { cout << "generic complex" << endl; } 
      static void f_(false_type) { cout << "generic real" << endl; } 
};   
template<> void Matrix<double>::f() { cout << "double" << endl; } 

Bằng cách này, tôi có thể sử dụng chức năng quá tải và mẫu để đạt được mục tiêu của mình.

0

Như mô tả trong câu trả lời liên quan, những gì bạn cần làm là chuyên toàn bộ lớp, chứ không phải là chức năng đơn giản:

#include <iostream> 
#include <complex> 
using namespace std; 

template <typename T> 
class Matrix { 
public : 
    static void f(); 
}; 

template<typename T> void Matrix<T>::f() { cout << "generic" << endl; } 
template<> void Matrix<double>::f() { cout << "double" << endl; } 

template <typename T> 
class Matrix<std::complex<T> > { 
public: 
    static void f() { cout << "complex" << endl; } 
}; 

int main(void) { 
    Matrix<complex<double> >::f(); 
    return 0; 
} 
+0

Tôi không hiểu. Tại sao tôi có thể dễ dàng chuyên nó cho đôi, nhưng không cho phức tạp ? Những gì tôi muốn là chính xác tránh chuyên toàn bộ lớp vì điều đó có nghĩa là tôi cần phải lặp lại mã cần được sử dụng lại. – Maxime

+0

Bạn cũng có thể trích xuất f thành một lớp khác và chuyên về tất cả những gì bạn muốn: Ma trận có thể thực hiện 'f()' như 'SpecializedF :: f (...)' – UncleBens

3

Trong dòng 11 và 12 bạn có khai báo của chuyên môn hóa rõ ràng cho một thành viên của một mẫu lớp được cho phép bởi C++ Standard 14.7/3 (14.5.2/2 có chứa một ví dụ tốt quá). Trong dòng 13 bạn đang cố gắng chuyên biệt hóa một phần mẫu lớp và không được phép trong biểu mẫu này (đây là chuyên môn từng phần vì bạn không biết toàn bộ loại std::complex<T> vì nó vẫn còn phụ thuộc vào T). Bạn nên một phần chuyên về cả lớp.

+0

như Assaf Lavie đề xuất, mẫu tham số mẫu mà không cần phải một phần chuyên toàn bộ lớp học? Một loạt các chức năng sẽ giống nhau, nó là đôi hoặc phức tạp hoặc phao. Tôi không muốn sao chép tất cả các chức năng này. – Maxime

+0

Có lẽ một ý tưởng hay là di chuyển tất cả các hàm chung vào lớp cơ sở và một phần chỉ chuyên lớp kế thừa. –