2010-08-10 26 views
19

Reading C++ Templates: The Complete Guide và nó nóiTại sao các mẫu không thể được khai báo trong một hàm?

Lưu ý rằng các mẫu không thể được khai báo trong một chức năng

Nó không đưa ra lời giải thích và/hoặc tham chiếu chéo với bất kỳ chương khác trong cuốn sách hoặc tài nguyên bên ngoài.

Ai đó có thể giúp giải thích điều này. Có lẽ nó được giải thích sau trong cuốn sách nhưng chưa có. Nếu được giải thích trước đó, tôi phải bỏ lỡ nó.

Ví dụ:

int main() 
{ 
    class DummyClass // This compiles ok 
    { 
    int object; 
    }; 

    template <typename T> // compile error "expected primary-expression before "template"" 
    class DummyTemplate 
    { 
    T object; 
    }; 

    return 0; 
} 

Tôi không hiểu được thông báo lỗi từ gcc một trong hai. Các thông báo lỗi nói:

expected primary-expression before "template" 
+0

Bạn không thể khai báo lớp học mới, đó chỉ là cách nó là, tôi đoán. –

+1

Có một số câu trả lời cơ bản nói "bạn không thể vì bạn không thể". Có ai biết liệu có lý do chính đáng để ngăn chặn việc này không? –

+0

Đối số mẫu phải có liên kết bên ngoài. Về lý do tại sao đây là một điều cần thiết có một số gợi ý được cung cấp bởi Greg Comeau trong clC++ này. Thảo luận được kiểm duyệt @ http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/f822a008746d1e68/2e9e48a43743e9e1 ? lnk = gst & q = lý do tại sao + local + templates # 2e9e48a43743e9e1 – Abhay

Trả lời

0

Nó có nghĩa là bạn không thể làm một cái gì đó giống như

void foo() 
    { 
     template <typename T> //Error 
     T something; 
    } 

tờ khai mẫu sau đây chỉ được phép ở, không gian tên, hoặc phạm vi lớp học toàn cầu. :)

Lý do đằng sau nó là gì?

Không được phép vì tiêu chuẩn nói như vậy.

ISO C++ - 98 (Mục 14,2)

Một mẫu khai có thể xuất hiện chỉ như là một lời tuyên bố phạm vi không gian tên hoặc lớp học.

Điều đó có hợp lý không?

+2

yes.Thanks. Câu hỏi đặt ra là tại sao lại như vậy. Lý do đằng sau nó là gì? – dubnde

+3

'Lý do đằng sau nó là gì?'. Tôi không biết nhiều kỹ thuật liên quan đến việc thực hiện khai báo mẫu bên trong một hàm nhưng nó không được phép theo tiêu chuẩn. ** ISO C++ (14.2) ** nói 'Khai báo mẫu * * có thể chỉ xuất hiện dưới dạng không gian tên hoặc khai báo phạm vi lớp ':) –

+4

+1. Cảm ơn. Có nó có ý nghĩa. Tôi thấy tiêu chuẩn không cho phép nó. Nó sẽ giúp hiểu tại sao mặc dù. Tôi đã thấy các câu hỏi về những tiêu chuẩn nào (không) cho phép trả lời với một số giải thích để trả lại tiêu chuẩn. Rất hữu ích cho những người học như tôi. Điều này không bao giờ lấy đi bất cứ điều gì từ câu trả lời rất tốt này. – dubnde

0

Chính xác thì việc sử dụng sẽ là gì? Vì vậy, bạn có thể khai báo các biến mẫu mà bạn chỉ có thể sử dụng trong hàm? Điều đó thực sự hữu ích?

+0

+1 để tránh mã hỗn loạn. –

+0

Có. Tôi có thể làm điều này với cấu trúc và lớp học. Chỉ có một người mà tôi có thể nghĩ đến là các đối tượng chức năng liên quan đến các lớp/cấu trúc để sử dụng với các thuật toán trong một hàm. Không bắt buộc nhưng tôi làm điều đó để giữ cho các lớp/cấu trúc gần với nơi tôi sử dụng chúng. Có lẽ tôi có thể có một số lý do nhưng điều này là nhiều hơn một bài tập học tập. Thực tế nó có thể không hữu ích là một cuộc thảo luận khác tôi đoán. – dubnde

+0

Tính hữu ích của nó không thực sự là một cuộc thảo luận khác, IMO nó rất phù hợp với điều này. Nếu điều này thực sự được cho phép, bạn sẽ sử dụng nó như thế nào? Phần bên trong của một hàm không hiển thị cho người gọi, vậy làm thế nào bạn sẽ khởi tạo tham số mẫu với kiểu thích hợp khi gọi hàm này? – Praetorian

2

Câu trả lời ngắn gọn về lý do tại sao điều này là do những người viết trình biên dịch và tiêu chuẩn c/C++ muốn nó như thế nào. Các khuôn mẫu bên trong các hàm phải được coi là quá hỗn loạn và/hoặc khó hiểu hoặc phân tích cú pháp, vì vậy chúng cấm nó.

+0

Cảm ơn. Rất dễ hiểu và có thể thấy điều đó có ý nghĩa rất nhiều. Bất kỳ tài liệu tham khảo? – dubnde

+0

@MeThinks: Xem nhận xét của tôi về nhận xét của bạn. –

1

Thời gian duy nhất này sẽ hữu ích nếu bạn tạo nhiều bản sao của mẫu với các loại khác nhau bằng một hàm. Tuy nhiên, hãy chuyển các lớp riêng tư ra khỏi các hàm của bạn. Nếu điều đó bắt đầu làm lộn xộn các lớp học của bạn thì chúng quá lớn và cần phải được tái cấu trúc.

+0

Đây là lời khuyên tốt. – dubnde

+2

Tuy nhiên, tôi đồng ý rằng đó là sự mâu thuẫn kỳ lạ trong ngôn ngữ. Giống như mọi người khác nói, chỉ cần viết nó xuống: "bởi vì đó là cách nó." – Cirdec

1

Tôi đoán là khó triển khai, đó là lý do tại sao nó không được phép. Việc viết các mẫu lớp bên ngoài các hàm là một giải pháp có thể chấp nhận được từ tay kia.

26

Sự cố có thể liên quan đến các mẫu cách lịch sử đã được triển khai: các kỹ thuật triển khai sớm (và một số vẫn được sử dụng ngày nay) yêu cầu tất cả các biểu tượng trong một mẫu có liên kết bên ngoài. (Instantiation được thực hiện bằng cách tạo ra các mã tương đương trong một tập tin riêng biệt.) Và các tên được định nghĩa bên trong một hàm không bao giờ có liên kết và không thể được gọi ra bên ngoài phạm vi mà chúng được định nghĩa.

+1

có vẻ hợp lý. – iammilind

+4

Đây phải là câu trả lời được chấp nhận, vì ít nhất nó đã cố gắng đưa ra lý do đằng sau nó, không chỉ "vì tiêu chuẩn nói như vậy." –

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