2009-09-13 6 views
6

Xét đoạn mã sau:Đúc con trỏ như mẫu đối số: Comeau & MSVC biên dịch, GCC không

template<int* a> 
class base {}; 

int main() 
{ 
    base<(int*)0> test; 
    return 0; 
} 

Cả Comeau và MSVC biên dịch này mà không có vấn đề (trừ Comeau cảnh báo về một biến không sử dụng), trong khi GCC thất bại trên dòng base<(int*)0> test;, nêu rõ

In function `int main()': a casts to a type other than an integral or enumeration type cannot appear in a constant-expression

template argument 1 is invalid

Chính xác thì nó phàn nàn về điều gì? Và ai đúng - mã này có nên biên dịch không? Cần lưu ý rằng phiên bản GCC của tôi là cực kỳ cũ (3.4.2) để có thể liên quan đến nó. Cảm ơn.

+0

FYI: với gcc 4.4.1: test.cpp: 6: lỗi: diễn viên cho loại không phải là loại tích phân hoặc kiểu liệt kê không thể xuất hiện trong biểu thức hằng số test.cpp: 6: error: template đối số 1 không hợp lệ test.cpp: 6: lỗi: loại khai báo không hợp lệ trước ';' token – jdehaan

+0

Cảm ơn jdehaan, vì vậy chúng tôi biết điều này không liên quan gì đến phiên bản của mình. – GRB

+0

Chào mừng Ur. Tôi đã thử sửa đổi mã một chút để làm cho nó biên dịch. Các biến thể nhẹ không làm rõ vấn đề ... – jdehaan

Trả lời

8

Từ một draft standard (nhấn mạnh thêm):

 
14.1.3 A non-type template-parameter shall have one of the following (option- 
    ally cv-qualified) types: 
    ... 
    --pointer to object, accepting an address constant expression desig- 
    nating a named object with external linkage, 
    ... 

Rõ ràng, đó là không hợp pháp để nhanh chóng một mẫu với một con trỏ null, như một con trỏ null không trỏ đến một "tên đối tượng với mối liên hệ bên ngoài" .

+0

SO liên quan: http://stackoverflow.com/questions/275871/how-to-overcome-gcc-restriction-could-not-convert-template-argument-0-to-foo – Managu

+1

+1! Tôi đã thử bằng cách đưa một con trỏ tới một tham số như là tham số và lỗi sau xuất hiện (tốt hơn so với thông số khá khó hiểu trước) lỗi: '& a' không phải là đối số mẫu hợp lệ của loại 'int *' vì 'a' không có liên kết bên ngoài – jdehaan

+1

Điều này có vẻ đầy hứa hẹn, nhưng tôi không nghĩ rằng điều này giải đáp tại sao GCC và Comeau lại khác nhau. Ví dụ, nếu tôi thay đổi thành 'base <(int*)1>', * cả * Comeau và GCC không biên dịch được. Ngoài ra, nếu yêu cầu này là từ 'dự thảo', thì GCC của tôi không thể biên dịch nó được 4 năm, vì vậy nếu điều này được thêm vào tiêu chuẩn trong thời gian đó, thì đó không phải là yêu cầu khiến GCC bị sặc . – GRB