Объявление SignedIntegral2
неправильно сформировано из-за [temp.concept] / 4 :
Концепция не должна иметь связанных ограничений.
И важно понять причину этого.Концепции в основном предикаты.Их работа состоит в том, чтобы взять ряд аргументов (чаще всего, ряд типов) и сказать, удовлетворена ли концепция или нет.Но подумайте, какой ответ дадут эти две разные реализации:
SignedIntegral<int32_t>
равен true
SignedIntegral<uint32_t>
равен false
SignedIntegral<string>
равенfalse
Но:
SignedIntegral2<int32_t>
равно true
SignedIntegral2<uint32_t>
равно false
SignedIntegral2<string>
is ... undefined
Весь смысл концепции заключается в ограничении.Предложенная альтернатива, краткая декларация в SignedIntegral2
ограничивает параметр типа T
равным Integral
.Поскольку string
не удовлетворяет Integral
, мы даже не можем задать вопрос, является ли это SignedIntegral2
.
Иными словами, SignedIntegral
- это общая функция, но SignedIntegral2
- это частичная функция, которая определена только для типов Integral
.Это может быть более понятным, если мы напишем обе эти функции на самом деле:
template <typename T>
constexpr bool SignedIntegral() { return Integral<T> && is_signed_v<T>; }
template <Integral T>
constexpr bool SignedIntegral2() { return is_signed_v<T>; }
Важно, чтобы понятия всегда были целыми функциями, поэтому связанные ограничения запрещены.
Обратите внимание, что в качестве расширения, безусловно, возможно рассматривать "undefined" как false
в целях удовлетворения концепций, но это добавило бы дополнительные складки к правилам подстановки, и это, безусловно, нетривиальная сложность реализации.Конечно, возможно, что какой-то будущий стандарт мог бы позволить им.Мой хрустальный шар сейчас в магазине, так что я не могу сказать точно.