2012-03-20 23 views
9

Tôi có một chức năng constexpr mà trông giống như sau:Làm thế nào để báo cho static_assert rằng các đối số hàm constexpr là const?

constexpr int foo(int bar) 
{ 
    static_assert(bar>arbitrary_number, "Use a lower number please"); 

    return something_const; 
} 

Tuy nhiên, biên dịch này với GCC 4.6.3 tiếp tục nói với tôi

lỗi: 'bar' không thể xuất hiện trong một hằng số thể hiện

tôi đã cố gắng một cái gì đó giống như

constexpr int foo(constexpr const int bar) 
{ 
    static_assert(bar>arbitrary_number, "Use a lower number please"); 

    return something_const; 
} 

nhưng constexpr không thể được sử dụng cho các đối số chức năng.

Có cách nào đơn giản để nói với trình biên dịch rằng thanh luôn luôn là một hằng số thời gian biên dịch?

+0

Rất tiếc, đã hoàn toàn quên mã hóa phần đó. Cảm ơn @Henrik – TravisG

+7

Một hàm constexpr có thể được gọi với các đối số không const, nó chỉ đơn giản là mất đi sự constexpr'ness của nó. –

+1

Cảm ơn, tôi không biết điều đó. – TravisG

Trả lời

16

Is there some simple way to tell the compiler that bar is always a compile time constant?

Nếu bar phải lúc nào cũng thời gian biên dịch liên tục, sau đó bạn nên viết chức năng của bạn như:

template<int bar> 
constexpr int foo() 
{ 
    static_assert(bar>arbitrary_number, "Use a lower number please"); 
    return something_const; 
} 

Bởi vì nếu bạn không làm như vậy, và thay vào đó viết những gì bạn đã viết, thì trong trường hợp đó, hàm có thể là được gọi với số cũng không phải là đối số; nó chỉ là khi bạn vượt qua đối số không const, sau đó hàm sẽ mất nó là constexpr -ness.

Lưu ý rằng trong mã trên arbitrary_number cũng phải là biểu thức liên tục, nếu không nó sẽ không biên dịch.

0

foo có thể được sử dụng trong các cách sau đây:

int i; 
std::cin >> i; 
foo("foo", i); 

Như bạn thấy i là không chính xác một biểu thức hằng ở trên, nhưng nó vẫn có thể được sử dụng với một constexpr chức năng. constexpr chức năng (và mẫu chức năng) là một con thú kỳ lạ đảm bảo rằng ví dụ foo(p, i) là một biểu thức liên tục iff pi cũng là, nhưng vẫn có thể được sử dụng như chức năng thông thường.

Nếu đối số cho hàm của bạn thực sự có nghĩa là luôn luôn là biểu thức không đổi, thì chúng phải là đối số mẫu, chứ không phải đối số hàm.

5

constexpr chức năng thể được đánh giá tại thời gian biên dịch, nó không bị ép buộc bởi các tiêu chuẩn nói chung (bạn có thể buộc các chức năng được đánh giá tại thời gian biên dịch bằng cách sử dụng nó bên trong một biểu thức hằng như khởi tạo một biến constexpr với nó) .

Ngoài ra, các đối số của hàm constexpr thực tế không phải là hằng số, chúng có thể thay đổi theo mọi cuộc gọi (ngay cả khi được đánh giá tại thời gian biên dịch).

Một công việc xung quanh là sử dụng mẫu không phải để nhập bar, nếu nó luôn là hằng số thời gian biên dịch (có vẻ như là).