
Le 10/01/13 15:46, Andrey Semashev a écrit :
On Thu, Jan 10, 2013 at 6:22 PM, Sebastian Redl <sebastian.redl@getdesigned.at> wrote:
On 10.01.2013 14:49, Andrey Semashev wrote:
I must be missing something crucial. My understanding was that constexpr functions should be evaluated at compile time, am I wrong? Yes. A constexpr function *can* be evaluated at compile time if all its arguments are constant expressions and evaluation using those arguments doesn't hit anything that isn't allowed (like a throw). If that is the case, the result itself may be used as a constant expression. Otherwise, it's a normal function call. Ok, thank you for clearing this.
A constexpr function only *must* be evaluated at compile time if the result has to be a constant expression. In that case, it is a compile time error if it cannot be evaluated. So, this means that my argument is still valid to some point. If array::at() is used in a constant expression and the check fails, the function is no longer valid. Changing my previous code sample to this:
template< typename T, unsigned int n > struct array { constexpr T at(unsigned int i) const { return i < n ? T() : throw 0; } };
template< int m > struct check { static int get() { return m; } };
int main(int, char*[]) { array< int, 5 > arr; check< arr.at(10) > a; return a::get(); }
produces the following error:
./constexpr_test.cpp: In function ‘int main(int, char**)’: ./constexpr_test.cpp:19:21: in constexpr expansion of ‘arr.array<T, n>::at [with T = int, unsigned int n = 5u](10u)’ ./constexpr_test.cpp:6:36: error: expression ‘<throw-expression>’ is not a constant-expression Have you tried declaring arr as a constexpr?
Vicente