2009-11-17 42 views
8

tôi đã có đoạn mã sau sử dụng các mẫu và kích thước của mảng như tham số mẫu không loạiC++ template tham số trong mảng chiều

template<int n> double f(double c[n]); 
... 
double c[5]; 
f<5>(c); // compiles 
f(c); // does not compile 

nên không trình biên dịch để có thể nhanh chóng f thứ hai mà không cần tham số mẫu rõ ràng? Tôi đang sử dụng g ++ 4.1

+0

MSVC sẽ cho phép bạn nhận được ngay với tội giết người. –

+0

VC8 sẽ không - ít nhất là không có cài đặt lành mạnh :) –

+0

Tôi đã nhầm lẫn. MSVC cho phép bạn làm đôi (& c) [n] rõ ràng, không giống nhau. Comeau cũng mát với double (& c) [n]. Tuyệt vời sự khác biệt một vài parens sẽ thực hiện. –

Trả lời

28

Nó hoạt động khi sử dụng tài liệu tham khảo:

template<size_t n> double f(double (&c)[n]); 
+0

cảm ơn đây là chính xác những gì tôi đã cần – Anycorn

1

Thật không may, bởi vì khi bạn vượt qua double c[5] đến f() hoặc bất kỳ mảng nào cho bất kỳ chức năng nào có mảng cho vấn đề đó, bạn sẽ mất thông tin về kích thước. Bạn chỉ đi qua một con trỏ.

Chỉnh sửa: Nhưng hãy xem câu trả lời của gf để giải quyết sự cố.

+2

Nhận xét của bạn, trong khi chính xác, không liên quan. Đúng, tại thời gian chạy không có cách nào để xác định kích thước của một mảng, nhưng việc khấu trừ tham số mẫu xảy ra tại thời gian biên dịch. Trình biên dịch biết rằng kích thước của mảng là 5 và có thể suy ra tham số mẫu cho phù hợp, mặc dù có một số hạn chế về điều đó. – boycy

+0

Không có cách nào trong thời gian chạy để xác định loại được khai báo ban đầu của * bất kỳ * nguyên thủy nào. Bạn sẽ mất thông tin khi bạn chuyển nó tới một hàm mong đợi một con trỏ, nhưng bạn mất nó theo cùng cách mà bạn mất thông tin khi bạn truyền một phao tới một hàm mong đợi một số nguyên. Cụ thể hơn, kiểu mảng tại thời điểm khai báo là "mảng 5 đôi", hoặc gấp đôi [5]. Các loại mảng có kích thước có một diễn viên tiềm ẩn cho một con trỏ. Diễn viên này quá phổ biến đến mức chúng ta có xu hướng quên nó không phải là kiểu gốc của mảng, nhưng nó chỉ là một kiểu hợp lệ như bất kỳ loại nào khác. –

0

không, bởi vì trong một cuộc gọi khác, đối số có thể đến từ mọi nơi. trình biên dịch chắc chắn không thể đuổi theo con trỏ của bạn khi chạy.

chỉnh sửa: btw, đây làm việc cho tôi, nhưng đòi hỏi -std = C++ 0x (Tôi đang sử dụng gcc 4,4)

#include <iostream> 

template <int n> 
struct T 
{ 
    T& 
    operator=(double const cc[n]) 
    { 
     c = cc; 
     return *this; 
    } 
    const double 
    operator[](int const &i) 
    { 
     return c[i]; 
    } 
    double c[n]; 
}; 

template<int n> 
double 
f(T<n> & x) 
{ 
    return x[n-1]; 
} 

int 
main() 
{ 
    T<5> t5 = {10, 20, 30, 40, 50}; 
    T<3> t3 = {100, 200, 300}; 
    std::cout << f(t5) << std::endl; 
    std::cout << f(t3) << std::endl; 
    return 0; 
} 
-1

Điều này có thể giúp bạn với vấn đề lớn hơn của bạn (bất cứ điều gì có thể được). Điều này sẽ cho phép bạn truy vấn kích thước/kiểu của mảng khi biên dịch.

template < typename T_, unsigned N_ > 
class many { 
public: 
    typedef T_ T; 
    enum { N = N_ }; 

    T array[N]; 
}; 

Justin

+0

Eh? Điều này giúp ích như thế nào? – bobbogo