2011-09-20 28 views
8

Tôi bị nhầm lẫn với cách mẫu C++ khởi tạo. Tôi có một đoạn mã:Tạo bản mẫu trong C++

template <class T, int arraySize> 
void test1(T (&array)[arraySize]) 
{ 
    cout << typeid(T).name() << endl; 
} 

template<class T> 
void test2(T &array) 
{ 
    cout << typeid(T).name() << endl; 
} 

int main() 
{ 
    int abc[5]; 
    test1(abc); 
    test2(abc); 
    return 0; 
} 

Dưới đây là những câu hỏi của tôi:
1. Làm thế nào để kích thước của mảng abc sẽ được chuyển cho Test1 (tham số arraySize)?
2. Trình biên dịch C++ xác định loại T trong hai mẫu như thế nào?

+1

Bạn có nghĩa là một cái gì đó như 'test1 (abc)'? Cái thứ hai không có ý nghĩa gì cả. Bạn có một hàm 'test2 ' và bạn đang lập chỉ mục nó như thể nó là một mảng ?! – Shahbaz

Trả lời

4

Trong test1 trình biên dịch tạo ra một mẫu với T [arraySize] là biểu mẫu của nó. Khi bạn gọi test1 (abc), bạn đang cung cấp đối số đầu vào của loại int [5] mà đối sánh mẫu tự động khớp.

Tuy nhiên, nếu bạn đã viết

int n=10; 
int *abc = new int[n]; 
test1(abc); 
test1<int,n>(abc); 

sau đó biên soạn sẽ thất bại và trình biên dịch sẽ cho rằng nó không có mẫu phù hợp với các test1 (abc) chức năng cuộc gọi hoặc test1 < int, n> (abc) gọi hàm.

Điều này là do kích thước abc được phân bổ động và do đó loại abc là một con trỏ có loại khác và do đó không có mẫu nào có thể khớp với hai cuộc gọi trên.

Các mã sau đây cho bạn thấy một số loại

#include <iostream> 
using namespace std; 

template <class T> void printName() {cout<<typeid(T).name()<<endl;} 

int main() 
{  
    printName<int[2]>(); //type = A2_i 
    printName<int*>();  //type = Pi 

    getchar(); 
    return 0; 
} 
+1

bên cạnh đó, 'abc [n]' sẽ không biên dịch, bởi vì C++ không hỗ trợ mảng có kích thước động (thậm chí không phải C++ 11, theo như tôi biết). Tôi đoán bạn có một nền C99? –

+0

Nó biên dịch tốt dưới táo 3.0 trình biên dịch mặc dù. Đã cập nhật câu trả lời. Cảm ơn bạn đã chỉ ra điều đó. – twerdster

7
  1. Không có tham số nào được truyền theo thời gian biên dịch.
  2. Cả hai arraySizeT được suy ra từ loại thông số array. Vì bạn vượt qua các số int[5], arraySizeT trở thành 5int, tương ứng, tại thời gian biên dịch.

Nếu, ví dụ, bạn khai báo int* abc = new int[5];, trình biên dịch của bạn sẽ bị chặn tại thời điểm bạn cố gắng gọi test1(abc). Ngoài kiểu không khớp kiểu cơ bản, int* không mang đủ thông tin để suy ra kích thước của mảng.

5

Được gọi là khấu trừ đối số mẫu.

Các loại của abc tại cuộc gọi tại chỗ là: int(&)[5] trong đó có hai thông tin kết hợp: int5. Và mẫu chức năng chấp nhận đối số của loại T(&)[N], nhưng đối số tại trang web gọi là int(&)[5], do đó trình biên dịch suy ra rằng TintN5.

Đọc những: