Đây là một trong các phần của tiêu chuẩn đã thay đổi từ C++ 03 thành C++ 11.
Trong C++ 03, [temp.arg.nontype] lượt đọc:
Mẫu đối số cho một tổ chức phi loại, phi mẫu template-tham số sẽ là một trong:
- [...]
- [...]
- địa chỉ của một đối tượng hoặc chức năng với liên kết bên ngoài, bao gồm mẫu chức năng và chức năng template-ids nhưng không bao gồm các thành viên lớp không tĩnh, thể hiện dưới dạng & id thể hiện nơi & là không bắt buộc nếu tên dùng để chỉ một hàm hoặc mảng hoặc nếu tham số mẫu tương ứng là tham chiếu; hoặc
- [...]
Trong C++ 11, mà đã được cập nhật như là kết quả của issue 1155, mặc dù GCC vẫn có a bug liên quan đến hành vi này:
- biểu thức liên tục (5.19) chỉ định địa chỉ của đối tượng hoàn chỉnh với thời lượng lưu trữ tĩnh và liên kết bên ngoài hoặc bên trong hoặc chức năng với liên kết bên ngoài hoặc bên trong , bao gồm hàm 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àm biểu thức id, biểu thức id là tên của đối tượng hoặc chức năng, ngoại trừ được bỏ qua nếu tên đề cập đến một hàm hoặc mảng và sẽ bị bỏ qua nếu tham số mẫu tương ứng là một tham chiếu; hoặc
Trong C++ 14, đơn giản hơn nữa và thậm chí không đề cập đến liên kết.
Đối với câu hỏi cụ thể của bạn, thông số extern
thêm liên kết bên ngoài vào baz_instance
. Không có nó, baz_instance
có liên kết nội bộ. Trong C++ 03, bạn cần liên kết bên ngoài để có tham số mẫu không kiểu tham chiếu. Trong C++ 11, bạn không còn nữa - vì vậy extern
không còn cần thiết nữa và nó biên dịch tốt mà không có nó.
Như bạn có thể thấy từ mã nguồn, baz không được xác định trong tệp nguồn khác. Hơn nữa nó sẽ không giải thích, tại sao thể hiện struct có thể được truyền cho một khuôn mẫu với bên ngoài, nhưng không thể không có bên ngoài. – smoes
Xem chỉnh sửa trong câu trả lời của tôi –