2014-12-30 11 views
16

Tôi nhận thấy rằng gcc 5.0 từ chối mã sau, trong khi clang 3.6 chấp nhận nó.Có thể sizeof lồng nhau hai lần bao giờ là một biểu thức phụ thuộc?

template<int n> 
struct I 
{ 
    typedef int Type; 
}; 

template<typename T> 
struct A 
{ 
    typedef I<sizeof(sizeof(T))>::Type Type; 
}; 

Hai biên dịch dường như khác nhau về việc liệu sizeof(sizeof(T)) là một biểu thức kiểu phụ thuộc hoặc giá trị phụ thuộc vào. Nếu biểu thức là phụ thuộc, sau đó nó theo sau rằng I<sizeof(sizeof(T))> là một loại phụ thuộc, có nghĩa là typename nên được yêu cầu.

này được bao phủ bởi các từ ngữ sau đây trong các tiêu chuẩn C++ 11:

[temp.dep.type]/8

Một loại phụ thuộc nếu nó là

  • một mẫu đơn giản-id trong đó tên mẫu là tham số mẫu hoặc bất kỳ mẫu nào trong số các đối số mẫu là loại phụ thuộc hoặc biểu thức phụ thuộc vào loại hoặc phụ thuộc vào giá trị

[temp.dep.expr]/4

Expressions trong các hình thức sau đây không bao giờ gõ phụ thuộc (vì kiểu của biểu thức không thể phụ thuộc):

sizeof unary-expression 
sizeof (type-id) 

[temp.dep.constexpr]/2

Biểu thức của biểu mẫu sau đây phụ thuộc vào giá trị nếu biểu thức đơn hoặc biểu thức được nhập độc lập hoặc loại id phụ thuộc:

sizeof unary-expression 
sizeof (type-id) 

giải thích của tôi là sizeof(T) bao giờ có thể loại phụ thuộc, có nghĩa sizeof(sizeof(T)) bao giờ có thể loại phụ thuộc hoặc giá trị phụ thuộc vào.

Đây có phải là lỗi trong gcc không?

+1

Ồ. GCC cũng nghĩ rằng 'sizeof n' phụ thuộc. http: // melpon.org/wandbox/permlink/BLobLBzkQXNRfDuq – willj

+0

Vâng, 'sizeof n' không phụ thuộc vào kiểu mà phụ thuộc vào giá trị. 'sizeof X', trong đó' X' là * không * loại phụ thuộc không phụ thuộc chút nào. Do đó, 'sizeof sizeof n' phải không phụ thuộc, phải không? – dyp

+0

Điều thú vị là biên dịch trên gcc 4.7.2, nhưng không thành công trên 4.9.0. – Barry

Trả lời

7

Tôi đang sử dụng bản nháp sau-N4296.

typedef I<sizeof(sizeof(T))>::Type Type; 

typename là cần thiết nếu các lồng nhau-tên-specifierI<..> phụ thuộc vào một mẫu tham số [temp.res]/5. Vì vậy, là I<..> phụ thuộc?

[temp.dep.type]/9 Một loại phụ thuộc nếu nó là

  • [...]
  • (9,7) một đơn giản-template-id trong đó một trong hai tên mẫu là thông số mẫu hoặc bất kỳ đối số mẫu nào là loại phụ thuộc hoặc một biểu thức là phụ thuộc loại hoặc phụ thuộc vào giá trị hoặc [...]

I<..> là một đơn giản-template-id, đối số mẫu là một biểu hiện. Biểu thức này có phải là sizeof(sizeof(T)) phụ thuộc vào loại hay phụ thuộc vào giá trị không?

Khái niệm sizeof(sizeof(T)) có thể được chia nhỏ thành các khái niệm sau:

 
expression   form 
=============================================== 
       T  type-id 
     sizeof(T)  sizeof (type-id) 
     (sizeof(T)) (expression) 
sizeof(sizeof(T)) sizeof unary-expression 

T không phải là một biểu hiện, nhưng tôi sẽ để nó trong danh sách cho sau này. Một ghi chú trên dấu ngoặc đơn: A biểu thức chính có thể là dấu ngoặc đơn (chung) . A Biểu thức đơn nhất có thể là biểu thức hậu tố có thể là biểu thức chính, do đó nó cũng có thể được dấu ngoặc đơn.

Một ngoặc biểu (X) phụ thuộc nếu X phụ thuộc:

[temp.dep.expr]/1 Trừ khi được mô tả dưới đây, một biểu thức là gõ phụ thuộc nếu có subexpression là gõ phụ thuộc.

[temp.dep.constexpr]/1 Trừ khi được mô tả bên dưới, cụm từ không đổi phụ thuộc vào giá trị nếu bất kỳ biểu thức con nào phụ thuộc vào giá trị.

Nói chung, sizeof biểu thức không bao giờ loại -dependent, bởi vì họ luôn luôn tạo ra một giá trị kiểu std::size_t:

[temp.dep.expr]/4 Expressions trong các hình thức sau đây không bao giờ gõ phụ thuộc vào (vì kiểu của biểu thức không thể phụ thuộc):

[...] 
sizeof unary-expression 
sizeof (type-id) 

Tuy nhiên, giá trị mà họ mang lại có thể phụ thuộc vào một mẫu tham số:

[temp.dep.constexpr]/2 Expressions có dạng sau là giá trị phụ thuộc vào nếu unary thể hiện hoặc biểu là loại phụ thuộc hoặc loại-id phụ thuộc:

sizeof unary-expression 
sizeof (type-id) 
 
expression   form      value-dep? type-dep? 
======================================================================= 
       T  type-id     no   yes 
     sizeof(T)  sizeof (type-id)   yes   no 
     (sizeof(T)) (expression)    yes   no 
sizeof(sizeof(T)) sizeof unary-expression no   no 

Kể từ Tloại phụ thuộc, sizeof(T) trở thành giá trị -dependent. Tuy nhiên, kể từ (sizeof(T))không nhập phụ thuộc, sizeof(sizeof(T)) không phụ thuộc.

+0

Điểm tốt trên bộ bên ngoài của dấu ngoặc đơn. Vì một lý do nào đó, tôi có dây cứng để viết 'sizeof (expression)' – willj

Các vấn đề liên quan