2014-09-17 30 views
10

Ai có thể cố gắng giải thích điều này?Hành vi constexpr lạ đối với lớp bên trong

template<typename T, size_t S = T::noElems()> 
struct C 
{ 
}; 

struct X 
{ 
    enum E { A, B, C }; 
    static constexpr size_t noElems() { return C+1; }; 
}; 

struct K 
{ 
    C<X> cx; // this DOES compile 
}; 

struct Y 
{ 
    struct Z 
    { 
     enum E { A, B, C }; 
     static constexpr size_t noElems() { return C+1; }; 
    }; 
    C<Z, Z::C+1> cyz; // this DOES compile 

    C<Z> cyz; // <--- this does NOT compile 
}; 
+0

Clang than phiền 'không xác định chức năng' noElems 'không thể được sử dụng trong một biểu thức liên tục' –

+2

Tôi nghĩ rằng nó có thể được trả lời [ở đây] (http://stackoverflow.com/a/8108406/4035785) –

+0

Bạn có thể thêm trình biên dịch không lỗi vào câu hỏi của bạn? – Angew

Trả lời

5

Với tuyên bố của struct

struct Y 
{ 
    struct Z 
    { 
     enum E { A, B, C }; 
     static constexpr size_t noElems() { return C+1; }; 
    }; 
    C<Z, Z::C+1> cyz1; // this DOES compile 

    C<Z> cyz2; // <--- this does NOT compile 
}; 

thực thể cyz1cyz2 được phân tích trước khi tuyên bố nội tuyến của Z::noElems(), vì vậy định nghĩa của

static constexpr size_t noElems() { return C+1; }; 

không có sẵn tại thời điểm tuyên bố của

C<Z> cyz2; 
+0

+1 Câu trả lời hay. Tự hỏi làm thế nào Z :: C có sẵn, sau đó. – gd1

+1

Tôi chỉnh sửa câu trả lời của tôi, tôi nghĩ rằng đó là về noElems là nội tuyến, mà làm cho trình biên dịch để phân tích nó sau khi khai báo của cyz, trong khi enum E có sẵn, đó là lý do tại sao cyz1 hoạt động –