#c #c 20
#c #c 20
Вопрос:
Я читал эту страницу cppreference и нашел в ней следующий код:
template <class G>
concept uniform_random_bit_generator =
// ...
requires {
// ...
requires std::bool_constant<(G::min() < G::max())>::value;
};
Мне любопытно, почему std::bool_constant
здесь используется. Разве это невозможно использовать requires G::min() < G::max();
напрямую, вот так:
template <class G>
concept uniform_random_bit_generator =
// ...
requires {
// ...
requires G::min() < G::max();
};
Ответ №1:
Потому что requires G::min() < G::max();
это серьезная ошибка, если G::min() < G::max()
не формирует постоянное выражение, а requires std::bool_constant<(G::min() < G::max())>::value
просто было бы false
.
Возьмем, к примеру, этот тип и эти понятия:
struct foo {
static int min();
static int max();
};
template<typename T>
concept min_max_1 = requires {
requires T::min() < T::max();
};
template<typename T>
concept min_max_2 = requires {
requires std::bool_constant<(T::min() < T::max())>::value;
};
// Which are entirely equivalent to
template<typename T>
concept min_max_1 = T::min() < T::max();
template<typename T>
concept min_max_2 = std::bool_constant<(T::min() < T::max())>::value;
static_assert(!min_max_2<foo>);
выполняется, как и ожидалось, поскольку формирует недопустимое выражение, поэтому оно равно false.
static_assert(!min_max_1<foo>);
создает ошибку времени компиляции, потому что T::min() < T::max()
это допустимое выражение, это просто не постоянное выражение bool, чего и следовало ожидать.