2012-06-28 23 views
5

Tôi nhận thấy rằng các xác nhận tĩnh trong các mẫu lớp không được kích hoạt khi các phiên âm là typedef 'ed.Có nên kích hoạt static_assert bằng typedef không?

#include <type_traits> 

template <typename T> 
struct test_assert 
{ 
    static_assert(std::is_same< T, int >::value, "should fail"); 
}; 

typedef test_assert<float> t; 

Mã này biên dịch không có lỗi. Nếu tôi cố gắng tạo ra một thể hiện, sau đó sự khẳng định thất bại:

t obj; // error: static assertion failed: "should fail" 

Cuối cùng, nếu tôi thay thế tình trạng này với false, sự khẳng định thất bại thậm chí nếu tôi không nhanh chóng các lớp mẫu:

template <typename T> 
struct test_assert 
{ 
    static_assert(false, "always fails"); 
}; 

Tôi đã thử mã này trên gcc-4.5.1 và gcc-4.7.0. Hành vi này có bình thường không? Vào thời điểm nào trình biên dịch phải xác minh các xác nhận tĩnh? Tôi đoán hai giai đoạn tra cứu có liên quan, nhưng không nên typedef kích hoạt giai đoạn thứ hai?

+0

+1. Câu hỏi tuyệt vời. :-) – Nawaz

Trả lời

9

Tôi đã thử mã này trên gcc-4.5.1 và gcc-4.7.0. Hành vi này có bình thường không?

lúc mấy giờ được trình biên dịch phải xác minh khẳng định tĩnh?

Đây là một câu hỏi thú vị. Trong quá trình khởi tạo, đây sẽ là lần tra cứu giai đoạn đầu tiên cho các tên không phụ thuộc và giai đoạn tra cứu thứ hai cho các xác nhận phụ thuộc vào các đối số mẫu.

đoán tra cứu hai pha có liên quan, nhưng không nên kích hoạt typedef giai đoạn thứ hai?

Mẫu được biên soạn theo yêu cầu, typedef vừa tạo bí danh cho mẫu và không kích hoạt trình diễn. Xét đoạn mã sau:

template <typename T> class unique_ptr; 
typedef unique_ptr<int> int_unique_ptr; 

Mẫu chỉ được khai báo, nhưng điều đó cũng đủ cho typedef, vì nó chỉ tạo ra một alias cho các loại. Ở phía bên kia, nếu bạn tạo một đối tượng kiểu, thì mẫu phải được khởi tạo (một lần nữa theo yêu cầu, các hàm thành viên sẽ không được khởi tạo).

+0

Cảm ơn, đây là những gì tôi nghĩ. Tôi đã rất ngạc nhiên vì tôi không bao giờ để ý rằng trong vài tháng lập trình meta mẫu. Thật vậy, trong TMP, 'typedef' thường truy cập một kiểu lồng nhau, kích hoạt instantiation. –

+0

+1 Câu trả lời hay! – Nawaz