2010-02-03 41 views
9

Tôi đã tập sau của mẫu:Templates chuyên môn

//1 
template< typename T > void funcT(T arg) 
{ 
    std::cout<<"1: template< typename T > void funcT(T arg)"; 
} 
//2 
template< typename T > void funcT(T * arg) 
{ 
    std::cout<<"2: template< typename T > void funcT(T * arg)"; 
} 
//3 
template<> void funcT<int>(int arg) 
{ 
    std::cout<<"3: template<> void funcT<int>(int arg)"; 
} 
//4 
template<> void funcT< int * >(int * arg) 
{ 
    std::cout<<"4: template<> void funcT< int *>(int * arg)"; 
} 

//... 

int x1 = 10; 
funcT(x1); 
funcT(&x1); 

Ai đó có thể vui lòng giải thích lý do tại sao funcT(x1); gọi hàm # 3 và funcT(&x1); gọi hàm # 2 nhưng không # 4 như mong đợi?
Tôi đã đọc bài viết này http://www.gotw.ca/publications/mill17.htm cho biết "độ phân giải quá tải bỏ qua các chuyên môn và chỉ hoạt động trên các mẫu chức năng cơ bản". Nhưng theo logic này funcT(x1); nên gọi hàm # 1, không phải # 3. Tôi bị bối rối.

+0

điều này dường như có liên quan: http://www.gotw.ca/publications/mill17.htm –

+0

tôi có thể gửi cho bạn một cuốn sách thực sự tốt cho điều này: Addison Wesley - C++ Templates - Hướng dẫn đầy đủ – erick2red

Trả lời

11

Hàm # 3 và # 4 là các chuyên ngành của số 1, không phải là số 1 và # 2 tương ứng.

Điều này có nghĩa là trình biên dịch của bạn sẽ chọn giữa # 1 và # 2 đầu tiên. Khi nó đã chọn # 1 là phù hợp nhất cho funcT (x1), sau đó chọn chuyên môn hóa, # 3. Đối với funcT (& x1), nó chọn # 2 là phù hợp nhất và không tìm thấy chuyên môn.

Bằng cách viết # 4 như

template<> void funcT<>(int * arg) 

nó trở thành một chuyên môn hóa của # 2 và bạn sẽ nhận được kết quả mong đợi rằng # 4 được gọi là cho funct (& x1).

Một lựa chọn khác sẽ được chỉ đơn giản là viết

void funcT(int *arg) 

từ chức năng thường xuyên sẽ luôn luôn được lựa chọn thay vì các phiên bản templated nếu chúng phù hợp.

+0

Phải. Bạn có thể thêm điều đó, để làm cho # 4 một chuyên môn hóa # 2 và nhận được hành vi "mong đợi", nó phải được viết là 'template <> void funcT <> (int * arg)' –

+0

@ Éric Malenfant: đúng, tôi ' m không chắc chắn cho dù bình luận của bạn hoặc chỉnh sửa của tôi đến trước, nhưng cảm ơn anyway. – villintehaspam

+0

Tại sao nó 'template <> void funcT <> (int * arg)' và không phải 'template <> void funcT (int * arg)'? – sepp2k

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