11

Tại sao là sản phẩm của code này:chức năng Chuyên mẫu với nhiều loại tài liệu tham khảo

#include <iostream> 
template<typename T> void f(T param) 
{ 
    std::cout << "General" << std::endl ; 
} 
template<> void f(int& param) 
{ 
    std::cout << "int&" << std::endl ; 
} 

int main() 
{ 
    float x ; f (x) ; 
    int y ; f (y) ; 
    int& z = y ; f (z) ; 
} 

chung
chung
chung

Người thứ ba là đáng ngạc nhiên vì chức năng chuyên biệt chính xác f hoặc int&

Chỉnh sửa: Tôi biết rằng quá tải có thể là giải pháp thích hợp. Tôi chỉ muốn học logic đằng sau nó.

+0

Có lẽ vì const int & được ưa chuộng để int &? – Septagram

+0

@Septagram: const int &? –

+0

Tôi không biết nếu nó giúp, nhưng nếu bạn thay đổi mẫu để chấp nhận một 'T &', thì cả hai 'f (y)' và 'f (z)' gọi phiên bản 'int &'. –

Trả lời

8

Loại của cả hai biểu thức y và biểu thức zint. Tham chiếu xuất hiện trong biểu thức sẽ không giữ loại tham chiếu. Thay vào đó, loại biểu thức sẽ là loại được tham chiếu, với biểu thức là một giá trị.

Vì vậy, trong cả hai trường hợp, T được khấu trừ thành int và do đó chuyên môn rõ ràng không được sử dụng.

Điều quan trọng cần lưu ý (ngoài việc bạn thực sự nên sử dụng quá tải, như một người khác đã nói), là bạn có tham số hàm không tham chiếu trong mẫu của bạn. Trước khi khấu trừ T đối với loại đối số được thực hiện, loại đối số sẽ được chuyển đổi từ mảng thành con trỏ thành phần tử đầu tiên của chúng (đối với hàm, đối số sẽ được chuyển thành con trỏ hàm). Do đó, một mẫu hàm có tham số hàm không tham chiếu không cho phép khấu trừ chính xác.

+1

+1 (và cảm ơn vì đã phát hiện lỗi trong câu trả lời của chính tôi khi tôi đang ở đó) –

1

Tham chiếu chỉ là bí danh, không phải là một loại. Vì vậy, khi bạn gọi f (z), nó khớp với phiên bản đầu tiên với T = int, đó là một lựa chọn tốt hơn mà T = int &. Nếu bạn thay đổi T thành T &, thì cả hai tham số int và int & sẽ gọi phiên bản thứ hai.

+0

Nếu tôi thay đổi T thành T &, tôi có lỗi trình biên dịch khi 'f (2)' hoặc 'f (" văn bản ")' –

+0

Thay đổi nó thành const. –

0

Tôi biết nó không được trả lời nhưng, IMHO bạn có thể thử này, với một đặc điểm giống như cách tiếp cận trong một cấu trúc:

template<typename T> 
struct value_traits 
{ 
    static void print(){std::cout << "General" << std::endl ;} 
}; 

template<> 
struct value_traits<const long> 
{ 
    static void print(){std::cout << "const long" << std::endl ;} 
}; 

template<> 
struct value_traits<std::vector<unsigned char> > 
{ 
    static void print(){std::cout << "std::vector<unsigned char>" << std::endl ; } 
}; 

template<> 
struct value_traits<const int> 
{ 
     static void print(){std::cout << "const int" << std::endl ;} 
}; 
Các vấn đề liên quan