2011-11-03 30 views
6

Chuẩn ISO 98/03 (phần 14.3.1) dường như cấm sử dụng loại có liên kết nội bộ làm tham số mẫu. (Xem ví dụ dưới đây.) Tiêu chuẩn C++ 11 thì không. G ++ - sử dụng tiêu chuẩn cũ - cho phép nó. Tôi có đang hiểu sai tiêu chuẩn 03, hay là g ++ chỉ cho phép trang trình bày này?Kiểu nội bộ làm đối số mẫu

namespace 
{ 
    struct hidden { }; 
} 

template<typename T> 
struct S 
{ 
    T t; 
}; 

int main() 
{ 
    S<hidden> s; 
    return 0; 
} 
+0

nào Phiên bản g ++? Có thể là tiện ích mở rộng –

Trả lời

7

Bạn đúng là C++ 03 không cho phép sử dụng loại có liên kết nội bộ làm thông số loại mẫu, trong khi C++ 11 thực hiện.

Tôi có vẻ nhớ lại, tuy nhiên, các định nghĩa bên trong không gian tên ẩn danh vẫn có liên kết bên ngoài.


Yup, mục 3.5 [basic.link] nói

Một tên có phạm vi không gian tên (3.3.5) có mối liên kết nội bộ nếu nó là tên của

  • một đối tượng, tài liệu tham khảo, chức năng hoặc mẫu chức năng được khai báo rõ ràng là tĩnh hoặc,
  • một đối tượng hoặc tham chiếu được khai báo rõ ràng const và không được khai báo rõ ràng extern cũng không được khai báo trước đó để có liên kết bên ngoài; hoặc
  • thành viên dữ liệu của liên minh ẩn danh.

Một tên có phạm vi không gian tên có mối liên hệ bên ngoài nếu nó là tên của

  • một đối tượng hoặc tài liệu tham khảo, trừ khi nó có mối liên kết nội bộ; hoặc
  • một hàm, trừ khi nó có liên kết nội bộ; hoặc
  • một lớp được đặt tên (điều 9) hoặc một lớp chưa đặt tên được xác định trong khai báo typedef trong đó lớp có tên typedef cho mục đích liên kết (7.1.3); hoặc
  • một điều tra được đặt tên (7.2) hoặc một điều tra chưa được xác định được xác định trong khai báo typedef trong đó điều tra có tên typedef cho mục đích liên kết (7.1.3); hoặc
  • một điều tra thuộc một điều tra có liên kết bên ngoài; hoặc
  • mẫu, trừ khi đó là mẫu chức năng có liên kết nội bộ (điều 14); hoặc
  • không gian tên (7.3), trừ khi nó được khai báo trong không gian tên chưa đặt tên.

Bạn có một lớp được đặt tên ở phạm vi không gian tên, nó có liên kết bên ngoài.

Và chú thích trên dưới cùng của trang 115 của tiêu chuẩn ISO/IEC 14882: 2003 làm rõ:

Mặc dù các tổ chức trong một không gian tên vô danh có thể có mối liên hệ bên ngoài, họ có đủ điều kiện có hiệu quả bởi một tên duy nhất cho bản dịch của họ đơn vị và do đó không bao giờ có thể được nhìn thấy từ bất kỳ đơn vị dịch thuật nào khác.

Nếu bạn có phiên bản khác, hãy thử tìm trong phần 7.3.1.1 [namespace.unnamed]

4

Đó không phải là ví dụ hợp lệ của quy tắc. Lớp hidden trong ví dụ của bạn có liên kết bên ngoài bên ngoài. (Nó có một tên duy nhất trình biên dịch tạo ra như vậy mà không có gì ngoài các đơn vị dịch hiện tại thực sự có thể liên kết với nó, nhưng nó vẫn còn bên ngoài.)

Các tiêu chuẩn đưa ra một ví dụ về một loại địa phương:

template <class T> class X { /* ... */ }; 
void f() 
{ 
    struct S { /* ... */ }; 

    X<S> x3; // error: local type used as template-argument 
    X<S*> x4; // error: pointer to local type used as template-argument 
} 
Các vấn đề liên quan