Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get min / max value of a static constexpr array at compile time

Let's say I have an array of integers defined like that:

static constexpr int IntArray[] = {1, 5, 10, 12, 17}; 

Is there a way to get the minimum or maximum value at compile time?

like image 591
lucaboni Avatar asked Oct 27 '16 13:10

lucaboni


People also ask

Are constexpr evaluated at compile time?

A constexpr function that is eligible to be evaluated at compile-time will only be evaluated at compile-time if the return value is used where a constant expression is required. Otherwise, compile-time evaluation is not guaranteed.

Should constexpr be static?

So you should definitely use static constexpr in your example. However, there is one case where you wouldn't want to use static constexpr . Unless a constexpr declared object is either ODR-used or declared static , the compiler is free to not include it at all.

Why does constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.

Is constexpr implicitly static?

constexpr functions are implicitly inline , but not implicitly static .


1 Answers

Let's get the C++17 solution out of the way for future search-landers:

constexpr int IntArray[] = {1, 5, 10, 12, 17}; constexpr int min = *std::min_element(std::begin(IntArray), std::end(IntArray)); static_assert(min == 1); 

C++11 is more picky with constexpr functions, so we have to roll out a recursive algorithm. This one is a simple, linear one:

template <class T> constexpr T &constexpr_min(T &a, T &b) {     return a > b ? b : a; }  template <class T> constexpr T &arrayMin_impl(T *begin, T *end) {     return begin + 1 == end         ? *begin         : constexpr_min(*begin, arrayMin_impl(begin + 1, end)); }  template <class T, std::size_t N> constexpr T &arrayMin(T(&arr)[N]) {     return arrayMin_impl(arr, arr + N); }  constexpr int IntArray[] = {1, 5, 10, 12, 17}; constexpr int min = arrayMin(IntArray); 

See it live on Coliru

like image 191
Quentin Avatar answered Sep 21 '22 23:09

Quentin