2013-06-27 9 views
6

Tại sao việc sử dụng biến cục bộ làm đối số không phải là bất hợp pháp?biến cục bộ dưới dạng đối số không phải tên tệp

Ví dụ: trong mã tiếp theo local_var không thể là đối số cho X.

template<int& x> struct X {}; 

void f(int local_var) 
{ 
    X<local_var> x; 
} 
+1

Đối số mẫu là một phần của * loại *. Loại 'x' sẽ là gì trong ví dụ của bạn? –

Trả lời

6

Vì đối số mẫu phải được đánh giá tại thời gian biên dịch và trình biên dịch sẽ không biết địa chỉ biến cục bộ cho đến thời gian chạy (để ràng buộc tham chiếu đến đối tượng, trình biên dịch cần biết địa chỉ của đối tượng đó).

Chú ý rằng do C++ 11 Tiêu chuẩn nói chính xác những gì không loại đối số mẫu có thể được quy định tại khoản 14.3.2/1:

Một mẫu đối số cho một tổ chức phi-type, không mẫu mẫu tham số sẽ là một trong:

- cho một tổ chức phi-type mẫu tham số của thiếu hoặc liệt kê loại, một hằng số biểu hiện chuyển đổi (5,19) của các loại của mẫu -parameter; hoặc

- tên của thông số mẫu không loại; hoặc

- một biểu thức hằng số (5,19) mà chỉ định địa chỉ của một đối tượng với thời gian tĩnh lưu trữ và liên kết bên ngoài hoặc nội bộ hoặc một chức năng với mối liên hệ bên ngoài hay bên trong, bao gồm cả chức năng mẫu và chức năng mẫu-id nhưng không bao gồm thành viên lớp không tĩnh, được biểu thị (bỏ qua dấu ngoặc đơn) là & id-expression, ngoại trừ & có thể bỏ qua nếu tên đề cập đến hàm hoặc mảng và sẽ bỏ qua nếu tham số-mẫu tương ứng là tài liệu tham khảo; hoặc

- biểu thức hằng số đánh giá thành giá trị con trỏ null (4.10); hoặc

- biểu thức liên tục đánh giá thành giá trị con trỏ thành viên null (4.11); hoặc

- con trỏ đến thành viên được thể hiện như mô tả trong 5.3.1; hoặc

- biểu thức hằng số địa chỉ loại std::nullptr_t.

Như bạn có thể thấy, các biến cục bộ không có trong danh sách này.

+0

Đợi, nhưng bạn có thể chuyển các hàm như các đối số mẫu và trình biên dịch cũng không biết địa chỉ của chúng cho đến khi chạy. – Mehrdad

+1

@Mehrdad: Không chắc tôi đang theo dõi bạn. Tại sao địa chỉ của hàm chỉ được biết đến trong thời gian chạy? –

+2

@Mehrdad: Các biến "cục bộ" (block-scoped) được loại trừ một cách rõ ràng bởi dấu đầu dòng thứ ba do Andy trích dẫn, vì chúng không có liên kết. Xem http://stackoverflow.com/questions/17348611/does-static-object-in-a-template-function-have-linkage/17350254#17350254 – rici

0

"Giá trị" của mẫu cần phải có mặt tại thời gian biên dịch.

template<int x> struct X {}; 

Ngay cả khi bạn không ràng buộc tham chiếu hoặc vượt qua con trỏ tại đây, trình biên dịch phải biết giá trị của các phần tử được chuyển vào lúc biên dịch.

Thay thế int &x bằng int x là mục đích tại đây. Nội dung về int & được trả lời chính xác. Tôi chỉ muốn nói rằng nó áp dụng cho tất cả các đối số mẫu không được nhập.

  • Các "giá trị" của một tham chiếu là một tài liệu tham khảo (thực hiện phụ thuộc thực sự là một con trỏ trong hầu hết trong số họ)
    • Địa chỉ của đối tượng phải được biết tại thời gian biên dịch
  • Các " giá trị "của một con trỏ template<int*> là một địa chỉ ...
    • ... mà tất nhiên phải được biết ở đây, tất nhiên.
  • Các "giá trị" của một giá trị kiểu là giá trị riêng của mình mà cũng phải được biết tại thời gian biên dịch

 

X<local_var> x; // will not work, local_var does not exist at compile time 
X<1> x; // works since 1 is known 

Tôi chỉ muốn (ngoài Andy câu trả lời) ngăn chặn bất kỳ kết luận nào đề xuất sử dụng loại giá trị thay vì tham chiếu.

+0

'mẫu ' khác với 'mẫu '. – aschepler

+0

Cảm ơn bạn đã trả lời nhưng như người cố vấn đã đề cập bạn đang diễn giải mẫu thay vì mẫu

+0

Cả hai bạn đều chính xác và đó là mục đích. Tôi sẽ có một chỉnh sửa nhanh về điều đó. – Pixelchemist