C++11: std::max(a,b) in static_assert()?
I noticed, that in [24.4.7] of the last C++-Std Doc N3291 max
ist not constexpr
:
template<class T> const T& max(const T& a, const T& b);
Therefore, it is not allowed to use it in a static_assert
for example. Correct开发者_如何学Python?
static_assert( max(sizeof(int),sizeof(float)) > 4, "bummer" );
That is correct.
I imagine the reason is simply that std::max
calls T::operator<
for an arbitrary type T
and for std::max
to be constexpr
, it would require T::operator<
to be constexpr
, which is unknown.
This is correct; std::min
and std::max
are not constexpr
, not even in the latest draft of C++14 (N3690), so they cannot be used within constant expressions.
There is no good reason for this, only bad reasons. The most significant bad reason is that the C++ committee is composed of individuals who have a limited amount of time to work on standardization, and no-one has put in the work required to make these functions constexpr
yet.
Note N3039, a change to the C++ standard adopted in 2010, that slightly extended the constexpr
facility specifically so that function such as min
and max
could be made constexpr
.
You can work around this by defining your own min
and max
functions:
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
this works on c++ 11
template<const Sz a,const Sz b> constexpr Sz staticMax() {return a>b?a:b;}
use:
staticMax<a,b>()
and of course a
and b
must be constexpr
精彩评论