
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 ./constexpr_test.cpp:19:23: note: in template argument for type ‘int’ ./constexpr_test.cpp:19:26: error: invalid type in declaration before ‘;’ token ./constexpr_test.cpp:20:12: error: ‘a’ is not a class, namespace, or enumeration Not exactly the error that is expected, I'd say.