C ++ 11: std :: max (a, b) в static_assert ()? - PullRequest
       52

C ++ 11: std :: max (a, b) в static_assert ()?

3 голосов
/ 21 августа 2011

Я заметил, что в [24.4.7] последнего C ++ - Std Doc N3291 max не constexpr:

template<class T> const T& max(const T& a, const T& b);

Следовательно, нельзя использовать его, например, в static_assert. Правильно?

static_assert( max(sizeof(int),sizeof(float)) > 4, "bummer" );

Ответы [ 2 ]

4 голосов
/ 21 августа 2011

Это правильно.

Я полагаю, причина в том, что std::max вызывает T::operator< для произвольного типа T и для std::max будет constexpr, для T::operator< будет constexpr, что неизвестно .

2 голосов
/ 20 июля 2013

Это правильно;std::min и std::max не constexpr, даже в последней версии C ++ 14 ( N3690 ), поэтому их нельзя использовать в константных выражениях.

Тамнет веских причин для этого, только плохие причины.Наиболее существенная причина состоит в том, что комитет C ++ состоит из людей, у которых ограниченное количество времени для работы над стандартизацией, и никто еще не вложил в работу, необходимую для выполнения этих функций constexpr.

Примечание N3039 , изменение к стандарту C ++, принятое в 2010 году, которое немного расширило возможности constexpr, в частности, для выполнения таких функций, как min и max constexpr.

Вы можете обойти это, определив свои собственные функции min и max:

template<typename T>
constexpr const T &c_min(const T &a, const T &b) {
  return b < a ? b : a;
}
template<typename T, class Compare>
constexpr const T &c_min(const T &a, const T &b, Compare comp) {
  return comp(b, a) ? b : a;
}
template<typename T>
constexpr const T &c_min_impl(const T *a, const T *b) {
  return a + 1 == b ? *a : c_min(*a, c_min_impl(a + 1, b));
}
template<typename T>
constexpr T c_min(std::initializer_list<T> t) {
  return c_min_impl(t.begin(), t.end());
}
// ... and so on
...