2010-09-25 26 views
7
#include <iostream> 
using namespace std; 
template<typename T> void test() 
{ 
    cout << "Called from template T"; 
} 
template<int I> void test() 
{ 
    cout << "Called from int"; 
} 
int main() 
{ 
    test<int()>();  
} 

Trong đoạn trên test<int()>() gọi là phiên bản đầu tiên và cho sản lượngMẫu nghi ngờ trong C++

Called from template T

Tại sao không phải là phiên bản thứ hai được gọi là?

+2

Trong ví dụ int() của bạn được hiểu là kiểu int (void) (tức là hàm). So sánh với std :: tr1 :: function . – FuleSnabel

Trả lời

11

Theo ISO C++ 03 (Section 14.3/2)

Trong một mẫu đối số, một sự nhập nhằng giữa một type-id và một biểu thức được giải quyết cho một type-id. int()type-id để phiên bản đầu tiên được gọi.

+2

Về mặt kỹ thuật, mặc dù bạn có thể đề cập đến việc sử dụng thử nghiệm <2>() sẽ gọi hàm thứ hai, vì '2' giải quyết thành' int'. – Zooba

9

Hãy thử:

test<(int())>(); 
+4

@sbi không có gợi ý hay, mặc dù bỏ sót một số lời giải thích. Các parens xung quanh 'int()' làm cho nó trở thành một biểu thức của kiểu 'int'. –

+2

@Johannes: Thật vậy. _I_ nên đã thử trước khi tôi buột miệng ... @tyms: Xin lỗi. Tôi đã xóa bỏ phiếu bầu của mình. (Nhưng tôi sẽ không bỏ phiếu vì điều này không giải thích lý do tại sao bạn làm việc.) – sbi

5

Nó không hoàn toàn rõ ràng với tôi những gì bạn đang cố gắng để đạt được với điều này. Nhưng nếu bạn muốn sử dụng một mẫu chuyên môn khác nhau khi bạn nhanh chóng các mẫu với một int chứ không phải bất kỳ loại khác thì đây là cú pháp bạn cần -

#include <iostream> 

    using namespace std; 

    template<typename T> void test() 
    { 
     cout << "Called from template T"; 
    } 

    template<> void test<int>() 
    { 
     cout << "Called from int"; 
    } 


    int main() 
    { 
      test<int>(); 

    } 
+3

'+ 1' cho câu trả lời duy nhất ở đây cho thấy làm thế nào để làm những gì, IMO, Rahul thực sự muốn làm - xác định một chuyên môn. – sbi

+0

Một chút OT: Nói chung tôi sẽ nói rằng phương pháp chuyên môn hóa không được khuyến khích. Herb Sutter kể câu chuyện hay hơn tôi: http://www.gotw.ca/publications/mill17.htm – FuleSnabel

+0

@FuleSnabel: Tôi tránh sử dụng quá tải thay vì thiếu chức năng _partial_ template đặc biệt, nhưng tôi đã luôn sử dụng chuyên môn _full_. – sbi

1

Tôi nghĩ rằng bạn muốn mẫu thứ hai được gọi bất cứ khi nào Tint. John has shown you cách thực hiện điều đó và Benoit has shown you những gì bạn cần làm để thực sự gọi hàm thứ hai.

Vấn đề của bạn là bằng cách cố gắng chuyêntest<>() cho một loại cụ thể (int) bằng cách sử dụng cú pháp hoàn toàn sai, bạn đã vô tình nhấn một hình thức cú pháp hợp lệ. (Loại may mắn.) Mẫu chức năng thứ hai đó đang sử dụng thông số mẫu không kiểu không kiểu. Đối với các loại bên cạnh, bạn có thể sử dụng những thứ khác làm thông số mẫu. Trong số các hàm khác (hàm, mẫu), bạn cũng có thể sử dụng hằng số tích phân, như int. Nếu bạn đã cố thực hiện điều này với, ví dụ: double, mã sẽ không thể biên dịch được.
Mẫu test<>() thứ hai của bạn là quá tải của mẫu đầu tiên có thể được sử dụng với số nguyên không đổi. Đó là lý do tại sao test<0>() của Benoit sẽ biên dịch.

Đối với một chuyên môn đầy đủ (không có phần chuyên môn hóa cho chức năng mẫu, có chỉ là quá tải; lớp mẫu, tuy nhiên, không có chuyên môn hóa một phần), bạn phải luôn luôn cung cấp một danh sách tham số mẫu trống (template<>) và đặt các loại chuyên biệt đằng sau mã định danh test<int>.

+0

Trong khi tôi đã làm rất nhiều điều sai trái trên toàn bộ chủ đề này, trừ khi bạn chỉ ra những gì sai với câu trả lời của tôi, nó không công bằng để bỏ phiếu xuống nó. – sbi

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