Understanding C ++ 14 Weakened Constexpr Constraints

I met a new C ++ 14 signature for the std::max function:

 template< class T > const T& max( const T& a, const T& b ); // (C++11) template< class T > constexpr const T& max( const T& a, const T& b );// (C++14) 

I read about Relaxed constexpr suggestions for C ++ 14, but I still don't understand why this function return value could be constexpr

Example:

 std::vector<int> a, b; //This does not compile but as my understadnding of `constexpr` this should int array[std::max(a.size(), b.size()]; (1) //This is trivial use that does compile int array[std::max(1,2)]; (2) 

When calling std::max in (1) is constexpr ignored?

+5
source share
1 answer

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. [...]

+10
source

All Articles