The underlying problem is not directly related to the weakened constexpr rules, the constexpr function is only a constant expression if the arguments are constant expressions. In your second case:
int array[std::max(1,2)];
this works because integer literals are really constant expressions.
C ++ 11 was more specific in this case, the draft C ++ 11 standard in section 5.19 [expr.const] outlines cases where a subexpression is not considered a constant expression and contains the following
calling the constexpr function with arguments that, when replaced by replacing the function call (7.1.5), do not produce a constant expression;
in C ++ 14, this paragraph has been deleted, and we have the following exception:
calling a function other than the constexpr constructor for a literal class, a constexpr function, or an implicit call to a trivial destructor (12.4) [Note: overload resolution (13.3) is applied as usual - note];
and we must use the rest of the rules regarding arguments (subexpressions).
In the first case:
int array[std::max(a.size(), b.size()];
std :: vector :: size is not marked as constexpr, and therefore it falls under the above exception.
Also note that in section 7.1.5 [dcl.constexpr] we have the following:
A call to the constexpr function produces the same result as a call to an equivalent non-constant function in all respects, except that a call to the constexpr function can appear in a constant expression.
Passing arguments to constexpr that are not constant expressions means that the expression is not available for use in contexts that require a constant expression.
Since dyp indicates that std::max not created constexpr in C ++ 11 due to various issues, including but not limited to conservative ones, we can see some of the problems related to N3039 . he is forgotten, see N3856 , which states:
This short document proposes to make the standard functions min and max constexpr. They were the main ones in the list of motivating cases for al-reducing the reference parameters for constexpr functions in C ++ 11. They were forgotten after the change in the main language was adopted.
For reference, we know that 1 and 2 are a constant expression from section 5.19 , which states:
A literal constant expression is a constant value expression of the prvalue type of literal type, but not a pointer type. integral constant expression is a literal constant expression of an integral or non-enumerated type of enumeration. [...]