2
votes

I'd like to build up a class with the option of constexpr-ness. And, of course, I'd like to take advantage of compile time error check.

Every constexpr function, constructor included, must work also at runtime, when the given parameters are not constant expression. That's should be the reason why every time you use static_assert in a constexpr function upon a function parameter it fails to compile.

Said so, I've read that one can use the exception throwing mechnanism, since when the function is called upon a constant expression, those exceptions can be evaluated at compile time. If that works, for functions the problem is solved.

But the problem is still not solved for constructors, since constexpr constructors seem to must have no body... so it looks like I can't use exception throwing from there!

Any idea?

1
You can use the comma operator. E.g: widget::widget() : value_((throw some_exception(), 0)) { }. Note that you don't have to use exceptions, it could be a call to a non-constexpr function also like std::abort. - Simple
...or an assert works as well: widget::widget(T t) : value_((assert(...), t)) {} - Casey
@Casey assert is a macro that may well expand to an if-statement; beware of compile errors when moving to another compiler. - Sebastian Redl
@SebastianRedl Per C99 (well, N1256 which is close) ยง7.2.1.1/2 "The assert macro puts diagnostic tests into programs; it expands to a void expression." - Casey
@Casey Ah, then I was wrong. - Sebastian Redl

1 Answers

7
votes

Following may help:

class A
{
public:
    constexpr A(int i) : i(i != 42 ? throw 42 : i) {}
private:
    int i;
};

int main(int argc, char *argv[])
{
    constexpr A a1(42);
    //constexpr A a2(41); // Compile error as expected.
    return 0;
}