Sự khác biệt giữa lớp mẫu và lớp mẫu là gì?


Câu trả lời:


125

Đây là điểm nhầm lẫn phổ biến đối với nhiều người (bao gồm cả trang Lập trình Chung trên Wikipedia, một số hướng dẫn C ++ và các câu trả lời khác trên trang này). Đối với C ++, không có cái gọi là "lớp mẫu", chỉ có một "khuôn mẫu lớp." Cách đọc cụm từ đó là "khuôn mẫu cho một lớp", trái ngược với "khuôn mẫu hàm", là "khuôn mẫu cho một hàm". Một lần nữa: các lớp không định nghĩa mẫu, mẫu xác định các lớp (và các hàm). Ví dụ: đây là một mẫu , cụ thể là một mẫu lớp , nhưng không phải là một lớp :

template<typename T> class MyClassTemplate
{ 
    ...
};

Khai báo MyClassTemplate<int> là một lớp, hoặc về cơ bản, một lớp dựa trên một khuôn mẫu. Không có thuộc tính đặc biệt nào của một lớp dựa trên mẫu so với một lớp không dựa trên mẫu. Các thuộc tính đặc biệt là của chính mẫu .

Cụm từ "lớp mẫu" không có nghĩa gì, bởi vì từ "mẫu" không có nghĩa như một tính từ khi áp dụng cho danh từ "lớp" theo như C ++ có liên quan. Điều đó ngụ ý sự tồn tại của một lớp (hay định nghĩa) một mẫu , mà không phải là một khái niệm tồn tại trong C ++.

Tôi hiểu sự nhầm lẫn phổ biến, vì nó có thể dựa trên thực tế là các từ xuất hiện theo thứ tự "lớp mẫu" trong ngôn ngữ thực tế, đó là một câu chuyện hoàn toàn khác.


+1. Đôi khi việc phân biệt "nguồn gốc" của một lớp sẽ hữu ích vì bất kỳ lý do gì, trong trường hợp đó, bạn có thể sử dụng hợp lý thuật ngữ "lớp mẫu" - nhưng vì những lý do bạn đã đưa ra, bạn nên xác định cẩn thận ý của bạn. .
j_random_hacker

1
@j_random_hacker - xem câu trả lời của litb bên dưới, nhưng trong ngắn hạn, thuật ngữ ưa thích cho đó là "chuyên môn hóa mẫu lớp"
Không chắc chắn

@Not Sure: Thực ra tôi thấy "chuyên môn hóa mẫu lớp" hơi mơ hồ, vì nó cũng có thể đề cập đến quá trình xác định chuyên môn hóa rõ ràng hoặc một phần cho một mẫu - điều không cần thiết để tạo ra một "lớp học" thực tế. :) IMHO "tạo mẫu lớp" là thuật ngữ rõ ràng nhất.
j_random_hacker

2
@j_random_hacker: Có một thuật ngữ thích hợp cho nó - "chuyên môn hóa mẫu lớp rõ ràng" và "chuyên môn hóa mẫu lớp rõ ràng một phần.". Rắc rối, nhưng không mơ hồ :)
Không chắc

1
−1 Các điều khoản có ý nghĩa như thế nào đối với những người sử dụng các điều khoản. Bắt đầu phân tích các nghĩa đen là vô nghĩa. Chỉ cần thử nó với bất kỳ thuật ngữ nào khác từ cuộc sống hàng ngày hoặc kỹ thuật. Tóm lại, câu trả lời này là hogwash. Câu trả lời của SHH , trích lời Bjarne, là OK.
Chúc mừng và hth. - Alf

13

Bjarne Stroustrup, người tạo ra C ++, cho biết trong cuốn sách Ngôn ngữ lập trình C ++ ấn bản lần thứ 4 , 23.2.1 Định nghĩa mẫu:

Có những người phân biệt ngữ nghĩa giữa mẫu lớp thuật ngữ và lớp mẫu . Tôi không; điều đó sẽ quá tinh tế: vui lòng xem xét các điều khoản đó có thể hoán đổi cho nhau. Tương tự, tôi coi mẫu hàm có thể hoán đổi cho nhau với hàm mẫu .


12

Sự khác biệt là thuật ngữ "lớp mẫu" chỉ đơn giản là không tồn tại trong Tiêu chuẩn C ++. Đó là một thuật ngữ được sử dụng hầu hết bởi những người nghĩ rằng thuật ngữ "mẫu lớp" là khó hiểu (như các công ty Qt Nokia và trước đây là Trolltech).

Tiêu chuẩn không có khái niệm về nó, vì vậy những người khác có thể tạo ra sự khác biệt. Một số người sử dụng nó một cách đồng nghĩa và những người khác nói rằng thuật ngữ "lớp mẫu" đề cập đến một mẫu lớp được khởi tạo hoặc chuyên biệt rõ ràng, điều này sẽ làm cho nó tương đương với thuật ngữ "chuyên môn hóa mẫu lớp". Về mặt lịch sử, nó có ý nghĩa này. Các chú thích Reference Manual định nghĩa ở trang 343

Một lớp được tạo từ mẫu lớp được gọi là lớp mẫu, cũng như một lớp được xác định cụ thể với tên-lớp mẫu như tên của nó

Tên -lớp mẫu không phải đầu cuối tương đương với id khuôn mẫu không phải đầu cuối được sử dụng trong Tiêu chuẩn ngày nay và đi xuống template-name < arguments >.


Để bạn làm quen với các thuật ngữ ngày nay, điều này quan trọng hơn việc sử dụng các thuật ngữ cũ không rõ ràng

// (1) defines a class template
template<typename T> class A { }; 

// (2) defines a class template explicit specialization 
template<> class A<int> { };

// (3) defines a class template partial specialization
template<typename T> class A<T*> { };

// (4) explicitly instantiates A<char>. 
template class A<char>;

// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
  • ARM gọi lớp (2) và các lớp được tạo bởi (4) và (5) là lớp mẫu . Tôi không chắc liệu ARM đã biết về các chuyên môn hóa một phần hay chưa. Nhưng nếu vậy (3) không được gọi là lớp mẫu, vì (3) không định nghĩa một lớp, nhưng định nghĩa một khuôn mẫu.
  • Tiêu chuẩn hiện tại gọi lớp (2) và những lớp được tạo bởi (4) và (5) các chuyên môn của mẫu lớp . Và (3) được gọi là chuyên môn hóa từng phần , trái ngược với chuyên môn hóa rõ ràng . Đôi khi nó cũng gọi (3) một chuyên môn (3.2 / 5 - tuy nhiên với việc làm rõ các liên kết chéo), mặc dù tôi thấy điều này không hoàn toàn rõ ràng với tôi, vì nó định nghĩa "chuyên môn" là một "lớp, hàm hoặc lớp thành viên ", mà (3) không thỏa mãn.

3
Hehe. Vâng và một số người khác cũng vẫn đóng góp cho bộ đó. Đáng chú ý là C ++ Faq lite và tài liệu Qt. Tác giả của faq lite đã nói với tôi qua thư rằng anh ấy muốn đặt một mục Câu hỏi thường gặp khác giải thích rằng sử dụng từ "chuyên môn hóa" sẽ tốt hơn vì nó ít gây nhầm lẫn hơn (sử dụng "chuyên môn hóa rõ ràng" cho loại chuyên môn do người dùng viết, sau đó). Các bạn Qt nói với tôi là họ không muốn dùng thuật ngữ "class template" .... họ thấy nó quá "không tự nhiên". Quá tệ.
Johannes Schaub - litb

@ JohannesSchaub-litb: ARM được viết bởi Bjarne Stroustrup và Margaret Ellis, khoảng năm 1991 IIRC. Trích dẫn của bạn từ ARM mâu thuẫn với trích dẫn của SHH từ ấn bản thứ 4 của Bjarne TCPPL . Vì vậy, thật tốt khi bạn rút ra được sự phân biệt giữa thuật ngữ cũ (trước tiêu chuẩn) và thuật ngữ hiện tại.
Chúc mừng và hth. - Alf


1

Mẫu lớp là mẫu được sử dụng để tạo các lớp trong khi lớp mẫu là lớp được tạo bởi mẫu.


0

Lớp mẫu: Lớp có định nghĩa chung hoặc lớp có các tham số không được khởi tạo cho đến khi thông tin được cung cấp bởi máy khách. Nó được dùng để chỉ một biệt ngữ cho lớp template.simply đơn giản với mẫu tiền tố và sử dụng T. Mẫu lớp: Cấu trúc riêng lẻ của một lớp được chỉ định bởi một mẫu lớp gần giống như cách các đối tượng riêng lẻ được xây dựng bằng cách sử dụng một lớp. Nó được tham chiếu đến một đối tượng của lớp mẫu Ex- classname objectname (danh sách đối số)


0

Mẫu lớp là một lớp chung cho các loại đối tượng khác nhau. Về cơ bản, nó cung cấp một đặc tả để tạo các lớp dựa trên các tham số. Bất cứ khi nào một đối tượng mới được tạo, một lớp mới sẽ diễn ra trong bộ nhớ cho mục đích đó. Điều này được gọi là khởi tạo một mẫu lớp và mỗi phiên bản khởi tạo của lớp được gọi là lớp mẫu.


0

Hãy xem bài báo này (từ wg21 và được xuất bản năm 1992) :

Thuật ngữ nhất quán

Cho đến nay, phần lớn tranh luận và bất đồng liên quan đến thuật ngữ được sử dụng trong chương mô tả các mẫu. Thường xuyên nhất là ứng dụng khác nhau của 'function-template''template-function' để thể hiện những ý tưởng và ý định khác nhau. Vì không có cách đặt tên nhất quán nào được áp dụng, kết quả là gây nhầm lẫn và tranh cãi.

Đối với mục đích của tài liệu này, như một đề xuất để ủy ban chính thức thông qua trong các cuộc thảo luận về các mẫu và nhằm mục đích làm rõ tài liệu; Tôi đề xuất chúng ta nên áp dụng phương thức chính thức hóa, rằng '-template' ở cuối mô tả một tập hợp các loại hoặc chức năng được mô tả bởi một mẫu. Và rằng một 'mẫu-' đứng đầu , được sử dụng để mô tả định nghĩa mẫu của một phần của '-template' , chẳng hạn như a 'template-member-function'. Như vậy: -

  • 'function-template': Một tập hợp các chức năng được mô tả bởi một mẫu, tham số trên một số thông tin loại được cung cấp làm đối số cho mẫu đó. Ví dụ :-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
  • 'class-template': Một tập hợp các lớp được mô tả bởi một mẫu, tham số trên một số thông tin kiểu được cung cấp làm đối số cho mẫu đó. Ví dụ :-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
  • 'template-function': Thuật ngữ này không còn được phép nữa. **
  • 'template-class': Thuật ngữ này không được phép. **

  • 'member-function-template': Thuật ngữ này không được phép, vì nó mô tả thuộc tính hiện không được định nghĩa mẫu hỗ trợ. Sử dụng quy ước thuật ngữ ở trên, điều này sẽ mô tả một thành viên của một khuôn mẫu không phải lớp, mà định nghĩa của bản thân nó là một khuôn mẫu. Ví dụ :-

class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};

Tuy nhiên, vì các mẫu hiện bị giới hạn trong phạm vi toàn cầu, nên mẫu như vậy không hợp lệ.

  • 'template-static-member-function':
  • 'template-member-function':
  • 'template-static-member':
  • 'template-static-data-member ' template-member ': Các thuật ngữ thay thế cho định nghĩa của một thành viên có vẻ tách biệt với' mẫu lớp 'mà nó thuộc về. Ví dụ :-
template<class T> int S<T>::sep_member()
{ return i; }

Về Normallớp bạn mô tả ở trên: Tôi không biết rằng một khuôn mẫu-hàm-thành viên như vậy bị cấm. Nó được chấp nhận bởi tất cả các trình biên dịch mà tôi đã thử. Tôi đang thiếu gì?
dan_din_pantelimon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.