xem xét mã này:ADL và người bạn tiêm
template <int N>
struct X
{
friend void f(X *) {}
};
int main()
{
f((X<0> *)0); // Error?
}
trình biên dịch có vẻ nặng nề không đồng ý. (MSVC08/10 nói không, GCC < 4.5 nói có, nhưng 4,5 nói không, mặt trời 5.1 nói có, intel 11.1 nói có quá nhưng comeau nói không (cả hai đều là EDG)).
Theo "Mẫu C++ - Các hướng dẫn đầy đủ":
... người ta cho rằng một cuộc gọi liên quan đến một tra cứu cho bạn bè trong lớp liên quan thực sự làm cho lớp được khởi tạo .. Mặc dù điều này đã được dự định rõ ràng bởi những người đã viết tiêu chuẩn C++, nó không phải là được nêu rõ trong tiêu chuẩn.
Tôi không thể tìm thấy phần có liên quan trong tiêu chuẩn. Bất kỳ tài liệu tham khảo?
Hãy xem xét sự thay đổi này:
template <int N>
struct X
{
template <int M>
friend void f(X<M> *) {}
};
template <>
struct X<0>
{
};
int main()
{
X<1>();
f((X<0> *)0); // Error?
}
Vấn đề mấu chốt ở đây là thời tiết các chức năng hữu hiệu đối tiêm bởi X<1>
nên được hiển thị trong ADL cho X<0>
? Chúng có liên quan không? Tất cả các trình biên dịch được đề cập ở trên đều chấp nhận mã này, ngoại trừ Comeau chỉ chấp nhận nó ở chế độ thư giãn. Không chắc chắn những gì tiêu chuẩn đã nói về điều này hoặc.
Bạn sẽ làm gì với điều đó?
Ví dụ đầu tiên có thể được biên dịch không? – jpalecek
Cảm ơn :) Đây là nhiều hơn hoặc ít hơn những gì tôi nghi ngờ. Làm thế nào đến rất nhiều trình biên dịch nhận được rằng trường hợp thứ hai sai? Ngoài ra, tôi sẽ đánh giá cao nó nếu bạn có thể cung cấp tham chiếu vào tiêu chuẩn cho các dấu ngoặc kép khác nữa. – uj2
@ uj2 tốt, ít nhất clang vẫn giữ được vẻ đẹp so với GCC. Nó chính xác từ chối trường hợp thứ hai. Đặc biệt GCC có khá nhiều vấn đề về tính tuân thủ mẫu nên điều này không làm tôi ngạc nhiên. Các trích dẫn khác bạn đang cố gắng tìm các đoạn Tiêu chuẩn là gì? –