Trong định nghĩa mẫu, ta cần cung cấp một gợi ý cho trình biên dịch biết rằng một định danh không xác định là một kiểu. Trong danh sách các tham số mẫu, typename được sử dụng để chỉ định tham số kiểu.
typename identifier;
Lưu ý
Typename có thể được sử dụng bởi bất kỳ kiểu nào ở bất cứ đâu trong một khai báo hoặc định nghĩa của mẫu. Nó không được phép dùng để chỉ định với lớp cơ sở, trừ khi nó là đối số mẫu cho lớp cơ sở mẫu.
template <class T>
class C1 : typename T::InnerType // Error - typename not allowed.
{};
template <class T>
class C2 : A<typename T::InnerType> // typename OK.
{};
Từ khóa typename cũng có thể được sử dụng thay cho class trong danh sách tham số mẫu. Ví dụ, các lệnh sau là tương đương về mặt ngữ nghĩa:
template<class T1, class T2>...
template<typename T1, typename T2>...
Tại sao C++ lại hổ trợ cả hai từ khóa class và typename cho tham số mẫu
Trong các đặc tả mẫu ban đầu, C++ đã sử dụng lại từ khóa class hiện tại để chỉ định một tham số kiểu thay vì giới thiệu một từ khóa mới vì có thể phá vỡ các chương trình hiện có. Không phải là một từ khóa mới không được xem xét, mà chỉ là nó không được coi là cần thiết ở thời điểm đó.
Tuy nhiên, việc sử dụng lại các từ khóa hiện tại dường như luôn gieo rắc sự nhầm lẫn. Những gì có thể thấy là sử dụng class bị hạn chế hoặc giới hạn đối số kiểu mà người dùng có thể chỉ định là kiểu class chứ không phải là kiểu được dựng sẳn hoặc con trỏ. Vì vậy, việc không giới thiệu một từ khóa mới có vẻ là một sai lầm.
Trong quá trình chuẩn hóa, một số cấu trúc nhất định đã được phát hiện trong một định nghĩa mẫu là các biểu thức cần tính toán mặc dù chúng có nghĩa là để chỉ ra các khai báo.
template <class T>
class Demonstration {
public:
void method() {
T::A *aObj; // oops …
// …
};
Trong khi câu lệnh chứa aObj được dự định sẽ được hiểu là khai báo một con trỏ tới kiểu A lồng trong tham số kiểu T, cú pháp ngôn ngữ diễn giải nó như một biểu thức số học nhân thành phần tĩnh A của kiểu T với aObj và đưa ra kết quả. Có gì khó chịu không! (Loại tình huống khó xử này là không thể có trong lập trình tổng quát – không có cách nào để xác minh một cách an toàn rằng bất kỳ T nào chứa A để bộ thực thi có thể xây dựng một thể hiện của kiểu tổng quát một cách an toàn.)
Do đó,từ khóa mới là kiểu tự mô tả được ra đời. Khi áp dụng cho một khai báo, chẳng hạn như,
typename T::A* a6; // declare pointer to T ’s A
thì nó ra lệnh cho trình biên dịch coi câu lệnh tiếp theo là một khai báo.
Vì từ khóa class đã được sử dụng trong nhiều chương trình đã có trước đó, nên rất mất công sức để thay thế hoàn toàn từ khóa class bằng typename. C++ đã quyết định giữ cả hai từ khóa cho khai báo cũng như định nghĩa mẫu.
Để lại một bình luận