Xét đoạn mã sau:C++ chức năng phân giải lựa chọn phiên bản templated qua chức năng đơn giản
#include <iostream>
template<typename T>
void f(T t)
{
(void)t;
std::cout << "templated f(T)\n";
}
template<typename T>
void entry(T t)
{
f(t);
}
void f(double d)
{
(void)d;
std::cout << "normal f(double)\n";
}
int main()
{
double d = 0.0;
entry(d);
return 0;
}
Output:
templated f (T)
Tôi thấy ngạc nhiên này, bởi vì tôi nghĩ rằng các chức năng đồng bằng sẽ được lựa chọn trên bất kỳ phiên bản templated. Lý do tại sao điều này xảy ra?
Một điều tôi nhận thấy khi chơi xung quanh là: nếu tôi đặt các chức năng bình thường void f(double)
trước templated void entry(T)
chức năng mã sẽ gọi hàm bình thường, về cơ bản xuất ra:
f bình thường (đôi)
Vì vậy, câu hỏi khác của tôi: tại sao thứ tự quan trọng trong ví dụ cụ thể này?
Ok, ... tuy nhiên tôi nhận thấy rằng tra cứu bên trong một mẫu sẽ tìm thấy một tên ngay cả * sau * khai báo mẫu nếu nó là mẫu khác, thậm chí là chuyên môn hóa mẫu với kiểu cơ bản như 'double'. Tôi đã kiểm tra điều này bằng cách thay đổi hàm bình thường thành một khuôn mẫu chuyên biệt: 'template <> void f (double)'. Kết quả là mẫu chuyên biệt được gọi, mặc dù nó đã qua điểm khai báo của mã gọi. – Edenbridge
@Edenbridge Tra cứu tên luôn tìm mẫu chính. Việc khớp các chuyên môn xảy ra sau khi tra cứu tên và có một quy tắc khác: nếu mẫu được khởi tạo trước khi chuyên môn hóa một phần phù hợp nhất được khai báo, thì chương trình không đúng chuẩn mà không cần chẩn đoán.Nếu bạn có thêm bất kỳ thắc mắc nào, vui lòng đăng câu hỏi riêng. – Brian