2009-06-14 18 views
20

Khi tôi đang viết một hàm trong một lớp mẫu làm thế nào tôi có thể tìm ra T của tôi là gì?làm thế nào để truy vấn nếu (T == int) với mẫu lớp

ví dụ:

template <typename T> 
ostream& operator << (ostream &out,Vector<T>& vec) 
{ 
if (typename T == int) 
} 

Tôi có thể viết câu lệnh if ở trên để hoạt động?

+0

Chỉ cần để bạn biết, có khá nhiều sự đồng thuận rằng bạn đã chấp nhận câu trả lời sai. Có thể muốn unaccept nó và chọn một số khác. :) – jalf

+0

Cảm ơn mọi thông tin bạn đã nhập! Ban đầu tôi chấp nhận câu trả lời typeid bởi vì chuyên môn có vẻ như quá mức cần thiết cho chức năng đơn giản mà tôi đã viết, nhưng sau này tôi đã làm cho chức năng phức tạp hơn một chút vì vậy tôi đã chọn chuyên môn. – Meir

Trả lời

39

Something như thế này:

template< class T > 
struct TypeIsInt 
{ 
    static const bool value = false; 
}; 

template<> 
struct TypeIsInt<int> 
{ 
    static const bool value = true; 
}; 

template <typename T> 
ostream& operator << (ostream &out,Vector<T>& vec) 
{ 
    if (TypeIsInt<T>::value) 
    // ... 
} 
+0

Chúng tôi có thể mong đợi điều này được tối ưu hóa để chúng tôi không có thêm chi phí nếu trên mọi cuộc gọi không? –

10

Xác định nó một cách rõ ràng, ví dụ .:

template <> 
ostream& operator << (ostream &out,Vector<int>& vec) 
{ 
} 
+0

Xóa 'mẫu ' và nó sẽ ổn. – avakar

+0

cảm ơn, vì đã chỉ ra sai lầm, tôi đã không chạm vào C++ trong một thời gian, tôi không nhớ cách viết chuyên môn hóa cho các mẫu. –

+7

Không cần chuyên môn về mẫu. Ưu tiên quá tải đối với các chuyên môn về mẫu chức năng. Sau này đôi khi có thể gây ngạc nhiên. (Có một GOTW về chủ đề này) – jalf

8

Bằng cách này.

ostream & operator << (ostream &out, Vector<int> const & vec) 
{ 
    // ... 
} 

Trình biên dịch sẽ chọn chức năng này qua mẫu chức năng nếu bạn vượt qua Vector<int>.

Chỉnh sửa: Tôi đã tìm thấy this article, cố gắng giải thích lý do tại sao lại thích quá tải để chuyên môn hóa mẫu.

+0

+1 bởi vì nó là một bài viết tuyệt vời nhưng nếu bạn đọc "Đạo đức số 2", bạn nên làm cho nó trở thành một chuyên môn về mẫu lớp. Tôi không thể tin rằng tất cả những người khác chỉ bỏ qua bài viết này hoặc không đọc "Kiểu C++ vượt trội" – TimW

+0

+1: Luôn thích quá tải về chuyên môn hóa. –

9

Cách đơn giản nhất là để cung cấp một mẫu chuyên môn:

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

template <typename T> struct A { 
}; 

template <typename T > 
ostream & operator <<(ostream & os, A<T> & a ) { 
    return os << "not an int" << endl; 
} 


template <> 
ostream & operator <<(ostream & os, A<int> & a ) { 
    return os << "an int" << endl; 
} 

int main() { 
    A <double> ad; 
    cout << ad; 
    A <int> ai; 
    cout << ai; 
} 
+1

Bạn có dấu chấm phẩy sau định nghĩa mẫu chức năng thứ hai. Ngoài ra, tại sao bạn thích chuyên môn hóa mẫu hơn cho quá tải? – avakar

+0

Lạ - mã chính xác được biên dịch bằng g ++ không có lỗi! –

+6

Nếu bạn đang viết một mẫu hàm chính có khả năng cần chuyên môn, thích viết nó như là một mẫu hàm duy nhất không bao giờ nên chuyên biệt hoặc quá tải, và sau đó triển khai thực hiện mẫu chức năng như một handoff đơn giản vào một mẫu lớp có chứa một hàm tĩnh có cùng chữ ký. Mọi người đều có thể chuyên về cả hai phần này một cách đầy đủ và một phần, và không ảnh hưởng đến kết quả phân giải quá tải. – TimW

0

C++ mẫu không làm việc theo cách này. Ý tưởng chung của các mẫu được thể hiện một số điểm phổ biến cho nhiều loại khác nhau. Và trong trường hợp của bạn, bạn nên sử dụng chuyên môn mẫu.

template<class T> ostream& operator<< (ostream& out, const vector<T>& v) 
{ 
    // your general code for all type 
} 
// specialized template 
template<> ostream& operator<< <int>(ostream& out, const vector<int>& vec) 
{ 
    // your specific to iny type code goes here 
} 

Sau đó, C++ biên dịch sẽ gọi chức năng này khi bạn sử dụng kiểu int và thực hiện chung cho bất kỳ loại khác

std::vector<int> f(5, 5); 
std::cout << f; 
6

typeid không bao giờ là một ý tưởng tốt. Nó dựa trên RTTI. Bằng cách ở đây là câu trả lời của bạn: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.7

+0

Vì vậy, RTTI hiện không tốt? Và typeid được biết đến lúc biên dịch. – GManNickG

+0

vấn đề với RTTI là gì? – Meir

+0

typeid khá chậm. Chuyên môn về mẫu được thực hiện tại thời gian biên dịch trong khi chi phí typeid bạn chạy. Làm theo cách của bạn. Tham khảo: http: //www.velocityreviews.com/forums/t279741-how-do-you-know-datatype-when-using-templates.html – siddhant3s

10

đơn giản, giải pháp chung nhất: Chỉ cần viết một tình trạng quá tải đồng bằng cũ của hàm:

ostream& operator << (ostream &out,Vector<int>& vec) 
{ 
// Your int-specific implementation goes here 
} 

này giả định rằng các int và phi int phiên bản don' t có nhiều mã chung, vì bạn phải viết hai triển khai riêng biệt.

NẾU bạn muốn sử dụng một thực hiện chung của chức năng, chỉ với một tuyên bố if bên trong khác, sử dụng thực hiện Charles Bailey:

template< class T > 
struct TypeIsInt 
{ 
    static const bool value = false; 
}; 

template<> 
struct TypeIsInt<int> 
{ 
    static const bool value = true; 
}; 

template <typename T> 
ostream& operator << (ostream &out,Vector<T>& vec) 
{ 
    if (TypeIsInt<T>::value) { 
     // your int-specific code here 
    } 
} 

Nói chung, không sử dụng typeid nếu bạn không cần để.

6

Kể từ C++ 11 chúng tôi có std::is_same:

if (std::is_same<T, int>::value) ... 

Nó thực hiện tương tự như đặc điểm gợi ý TypeIsInt gợi ý trong câu trả lời khác, nhưng với hai loại được so sánh.

1

hơn Một giải pháp là:

if(std::is_same<T, int>::value) 
    //It is int 
if (std::is_same<T, double>::value) 
    //It is double 
if (std::is_same<T, long double>::value) 
    //It is long double 
Các vấn đề liên quan