Tôi kiểm tra mã trong tiêu chuẩn C++ ISO/IEC 14882-03 14.6.1/9 trên Xcode 4.1 và Visual Studio 2008. Kết quả đầu ra của hai trình biên dịch khác với kết quả mong đợi của tiêu chuẩn.Kết quả thực tế của độ phân giải tên trong mẫu lớp khác với tiêu chuẩn C++ 03
Mã được dán bên dưới.
#include <stdio.h>
#include <iostream>
using namespace std;
void f(char);
template <class T > void g(T t)
{
f(1);
f(T(1));
f(t);
}
void f(int);
void h()
{
g(2);
g('a');
}
void f(int)
{
cout << "f int" << endl;
}
void f(char)
{
cout << "f char" << endl;
}
int main() {
h();
return 0;
}
Như mô tả tiêu chuẩn. Sản lượng dự kiến phải là
f char
f int
f int
f char
f char
f char
Tạo và chạy mã trên Xcode 4.1. Đầu ra là như dưới đây. Trong các thiết lập xây dựng, tôi đã cố gắng thay đổi "Compiler for C/C++/Object-C" thành Apple LLVM Compiler 2.1, Gcc 4.2 và LLVM GCC 4.2. Các kết quả đầu ra là như nhau.
f char
f char
f char
f char
f char
f char
Tạo và chạy mã trên Microsoft Visual Studio 2008. Kết quả như sau.
f int
f int
f int
f int
f char
f char
Mô tả (14.6.1/9) của tiêu chuẩn được dán bên dưới.
Nếu tên không phụ thuộc vào thông số mẫu (như được định nghĩa trong 14.6.2), một tuyên bố (hoặc tập hợp các tuyên bố) cho tên đó phải nằm trong phạm vi tại điểm tên xuất hiện trong định nghĩa mẫu; tên được gắn kết với khai báo (hoặc khai báo) được tìm thấy tại thời điểm đó và ràng buộc này không bị ảnh hưởng bởi các khai báo có thể nhìn thấy tại điểm khởi tạo. [Ví dụ:
void f(char);
template<class T> void g(T t)
{
f(1); // f(char)
f(T(1)); // dependent
f(t); // dependent
dd++; // not dependent
}
void f(int);
double dd;
void h()
{
// error: declaration for dd not found
g(2); // will cause one call of f(char) followed // by two calls of f(int)
g(’a’); // will cause three calls of f(char)
-end dụ]
Mã này được tốt được hình thành với các trình biên dịch, nhưng những kết quả khác nhau. Sẽ rất nguy hiểm khi chuyển mã này sang các nền tảng khác nhau.
Ai đó có lý do tại sao những trình biên dịch này không tuân theo tiêu chuẩn?
Chỉnh sửa trên 10/11/2011
mỗi http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#197, ví dụ trong tiêu chuẩn là sai. Tôi kiểm tra mã dưới đây trên Clang và Gcc.
#include <stdio.h>
#include <iostream>
using namespace std;
void f(char);
template <class T > void g(T t)
{
f(1);
f(T(1));
f(t);
}
enum E{ e };
void f(E);
void h()
{
g(e);
g('a');
}
void f(E)
{
cout << "f E" << endl;
}
void f(char)
{
cout << "f char" << endl;
}
int main() {
h();
return 0;
}
Kết quả như mong đợi.
f char
f E
f E
f char
f char
f char
Cảm ơn,
Jeffrey
+1 cho câu hỏi đầu tiên tuyệt vời –
Điều thú vị là Clang 2.9 dường như có cùng vấn đề với gcc. –