2011-11-12 16 views
6

Nếu tôi cố gắng biên dịch đoạn mã sau C++ 0x, tôi nhận được một lỗi:Lỗi sử dụng một constexpr làm mẫu tham số trong cùng lớp

template<int n> struct foo { }; 

struct bar { 
    static constexpr int number() { return 256; } 

    void function(foo<number()> &); 
}; 

Với gcc 4.6.1, thông báo lỗi là :

test.cc:6:27: error: ‘static constexpr int bar::number()’ used before its definition 
test.cc:6:28: note: in template argument for type ‘int’ 

với vang 2.8, thông báo lỗi là:

test.cc:6:20: error: non-type template argument of type 'int' is not an integral 
     constant expression 
     void function(foo<number()> &); 
          ^~~~~~~~ 
1 error generated. 

Nếu tôi di chuyển constexpr chức năng đến một cơ sở c lass, nó hoạt động trên gcc, và đưa ra các thông báo lỗi tương tự trên kêu vang:

template<int n> struct foo { }; 

struct base { 
    static constexpr int number() { return 256; } 
}; 

struct bar : base { 
    void function(foo<number()> &); 
}; 

là sai mã, hoặc là nó một giới hạn hoặc lỗi về việc thực hiện gcc 4.6 của C++ 0x? Nếu mã sai, tại sao nó sai, và mệnh đề nào của tiêu chuẩn C++ 11 nói nó là không chính xác?

+2

Hmm .. Tôi nghĩ rằng chúng tôi chỉ thảo luận này trước đó: định nghĩa hàm nội tuyến được đối xử như thể họ được xác định * ngay sau * định nghĩa lớp; do đó, bên trong định nghĩa lớp, chúng chưa có sẵn. Lưu ý rằng bạn luôn có thể nói 'static const int number = 256;' hoặc 'static constexpr int number = 256;' thay vào đó. –

+0

@KerrekSB oh, tôi chưa bao giờ biết điều đó. Bạn nên viết như một câu trả lời. –

+0

@KerrekSB: AFAIK, nếu tôi sử dụng 'static const int number = 256;', tôi cũng cần một 'const int bar :: number;', sẽ lãng phí thêm 4 byte vô ích vào '.data'. Sử dụng một hàm inline ngăn chặn điều đó. Tôi không có ý tưởng nếu đó cũng là trường hợp cho 'static constexpr int number = 256;', tuy nhiên. – CesarB

Trả lời

5

Trong C++, định nghĩa nội tuyến của hàm thành viên cho một lớp chỉ được phân tích cú pháp sau mỗi lần khai báo trong lớp được phân tích cú pháp. Do đó, trong ví dụ đầu tiên của bạn, trình biên dịch không thể thấy định nghĩa của number() tại thời điểm mà function() được khai báo.

(Không có phiên bản phát hành của vang có hỗ trợ cho việc đánh giá chức năng constexpr, vì vậy không ai trong số testcases của bạn sẽ làm việc ở đó.)

1

Tôi đã có một lỗi simillar với đoạn mã sau:

struct Test{ 
    struct Sub{constexpr Sub(int i){}}; 
    static constexpr Sub s=0; 
}; 

"error: 'constexpr Test :: Sub :: Sub (int)' được gọi trong biểu thức hằng số" trên gcc 4.7.1. khi này sẽ biên dịch thành công:

struct Sub{constexpr Sub(int i){}}; 
struct Test{ 
    static constexpr Sub s=0; 
}; 
+4

Vui lòng chỉ cung cấp câu trả lời nếu những gì bạn đang đóng góp sẽ * trả lời * câu hỏi mà người dùng đang đặt ra. Những gì bạn đã đăng được coi là một nhận xét nhiều hơn, bạn sẽ nhận được đặc quyền để đăng khi bạn sử dụng trang web nhiều hơn. Cảm ơn bạn đã tham gia S.O. và chào mừng. – David