2016-10-27 2 views
42

Скажем, у меня есть массив целых чисел, определенный как то:Получить мин/макс значение статического массива constexpr во время компиляции

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

Есть ли способ, чтобы получить минимальное или максимальное значение во время компиляции?

+6

Можно было бы сделать это с рекурсивным [ 'constexpr'] (http://en.cppreference.com/w/cpp/language/constexpr). –

+0

В C++ может быть возможно использовать метапрограммирование шаблона для его решения. – vsz

ответ

61

Давайте получим решение C++ 17 из пути для будущих поисковых-спускаемых:

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 является более разборчивы с constexpr функций, поэтому мы должны выкатить рекурсивный алгоритм. Это один простой, линейный один:

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

+0

Здесь я вручную пытаюсь реализовать версию C++ 17, и там я уже один. :(Но хорошо знать.;) – Hayt

+0

Отличный ответ! Можете ли вы дать краткий комментарий о том, почему вы используете ссылки в качестве типов возврата? Это не будет работать иначе из-за противоречивого типа вычета (CV лишается из non-refs). – vsoftco

+0

@vsoftco нет особой причины, он просто более гибкий. Я не сталкиваюсь с какой-либо ошибкой, удалив их, не могли бы вы показать пример? – Quentin

Смежные вопросы