- A+

The standard says about template constexpr functions/constructors in dcl.constexpr/6:

If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed, no diagnostic required.

The interesting part is:

fail to satisfy the requirements for a ... constexpr constructor, that specialization is still a ... constexpr constructor

So, even if a constructor is marked with `constexpr`

, it may not be used in a constant expression.

Why does this rule exist? Why isn't `constexpr`

removed, when a function doesn't satisfy the requirements?

The current behavior is bad in two ways:

- the non-constexpr-ness isn't caught at the closest possible location, but at the actual constexpr expression, where it is used. So we have to find the offending part, where
`constexpr`

silently removed. - an object, which is intended to be statically initialized (because it has a
`constexpr`

constructor), will be dynamically initialized without any errors/warnings (because the constructor isn't "really" constexpr).

Does this rule have some pros, which balances the cons of it?

This rule allows you to write a templated constructor/function and mark it as `constexpr`

even when it's not always `constexpr`

(only at least sometimes).

For example, `std::pair`

has `constexpr`

constructors, but it is of course usable outside of constant expressions.

This is quite sensible, because otherwise you would have to duplicate all these functions (once with `constexpr`

and once without), even if the code is exactly the same. Let's not even consider ambiguity.

Since it is generally impossible to prove that a template cannot ever satisfy `constexpr`

, no diagnostic is required for it (but it's ill-formed so compilers can complain to you if they can prove this for a given case).

You are correct that this is not very useful if you want to specify "this function shall *only* be usable in constant expression", but that's not what this wording is aiming for.

Edit: To clarify, `constexpr`

**for functions** only means *"legal to evaluate inside a constant expression"* (more precise wording here), **not** *"can only be evaluated at compile-time"*. By contrast, `constexpr`

variables must be initialized with a constant expression.

Another edit: We have exact wording to discuss, thanks to @JackAidley!

If the instantiated template specialization of a constexpr function template would fail to satisfy the requirements for a constexpr function, the

`constexpr`

specifier is ignored and the specialization is not a constexpr function.

The problem with this is that "there is at least one set of arguments for which the function can be constant-evaluated" is part of the "requirements for a constexpr function". Therefore, compilers cannot implement this clause, since it is not possible to prove (in general) whether such a set exists for a given function (or a function template instantiation). You either have to muddy this requirement further or give up on this aspect. It seems the committee chose the latter.