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?
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 đó. –
@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. –
@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