Tôi muốn xác minh rằng sau đây là lỗi trong GCC và không phải trong sự hiểu biết của tôi về C++. Xét đoạn mã sau:Xác minh lỗi trong GCC
struct A
{
struct B
{
template< typename U > U as() const { return U(); }
};
B operator[](int) const { return B(); }
};
template< typename T >
struct as
{
template< typename U >
static T call(const U& u)
{
return u[ 0 ].as<T>(); // accepted by Clang 3.2, rejected by GCC 4.7
// return u[ 0 ].template as<T>(); // does not help and is IMHO not needed
// return u[ 0 ].A::B::as<T>(); // accepted by GCC 4.7
}
};
int main()
{
as<int>::call(A());
}
IMHO mã nên được tốt, nó được chấp nhận bởi Clang 3.2, nhưng không phải bởi GCC 4.7 (4.4 và 4.6 cũng thất bại với về cơ bản các lỗi tương tự nhưng 4.4 tạo ra một thông điệp hơi khác nhau) . Dưới đây là các đầu ra từ vỏ của tôi:
$ clang++-3.2 -O3 -Wall -Wextra -std=c++0x t.cc -o t
$ g++-4.7 -O3 -Wall -Wextra -std=c++0x t.cc -o t
t.cc: In static member function ‘static T as<T>::call(const U&)’:
t.cc:17:21: error: invalid use of ‘struct as<T>’
t.cc: In static member function ‘static T as<T>::call(const U&) [with U = A; T = int]’:
t.cc:18:4: warning: control reaches end of non-void function [-Wreturn-type]
$
Câu hỏi: Đây có phải là một lỗi trong GCC hay tôi thiếu cái gì?
EDIT: Tôi hơi bối rối: Báo cáo lỗi GCC tại số http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55576 cho biết tại nhận xét số 9 rằng mã trong nhận xét số 3 là "hợp lệ". Chính xác điều này có nghĩa là gì? Có vẻ như những người GCC nghĩ rằng nó thực sự là một lỗi, nếu không họ sẽ đóng nó? OTOH câu trả lời từ @Potatoswatter có vẻ khá rõ ràng rằng nó phải chính xác và tôi nên gửi báo cáo lỗi chống lại Clang (hoặc đã có báo cáo lỗi như vậy?)
Lưu ý rằng tôi ngần ngại đánh dấu câu trả lời là được chấp nhận cho đến khi trên được làm rõ. Vì cả hai câu trả lời đều hữu ích (một để giải thích, một câu trả lời cho công việc), tôi đã cho cả hai câu trả lời.
Câu hỏi về tiền thưởng: Vì tôi nhận được phiếu giảm giá cho mã không tường thuật, tôi tự hỏi người khác cảm thấy như thế nào. Tôi đã cố gắng để tạo ra một SCCEE mà loại bỏ tất cả các phiền nhiễu và tập trung vào các vấn đề kỹ thuật. Đó là cách tôi thích nghĩ về những điều này. Là sai đó?
Ngoài ra, @EdHeal: Tại sao mã dễ bị thiên tai? (Bạn không nghĩ đó là mã thế giới thực mà tôi có, phải không?)
EDIT2: Cảm ơn, David, vừa chú ý chỉnh sửa của bạn. Tôi sẽ đánh dấu câu trả lời của bạn là được chấp nhận ngay bây giờ và tôi cũng thấy rằng bạn đã nhận xét về báo cáo lỗi GCC. Tôi nghĩ rằng điểm chính của câu hỏi này là do đó được trả lời và GCC có một lời nhắc nhở khác. Cảm ơn mọi người.
Tôi tin rằng đây là lỗi đã biết. – Potatoswatter
Nhưng, như 'u [0]' là một biểu thức phụ thuộc, từ khóa 'template' là cần thiết. Trình phân tích cú pháp cần có khả năng tìm ra dấu hiệu '<' có nghĩa là không biết 'U' và không tìm kiếm một'> '. – Potatoswatter
Đó là những gì tôi thấy là tốt, Clang nên từ chối mã. – Xeo