Это правило позволяет вам написать шаблонный конструктор / функцию и пометить его как constexpr
, даже если это не всегда constexpr
(только по крайней мере иногда).
Например, std::pair
имеет constexpr
конструкторы , но, конечно, его можно использовать вне константных выражений.
Это очень разумно, потому что в противном случае вам придется дублировать все эти функции (один раз с constexpr
и один разбез), даже если код точно такой же.Давайте даже не будем рассматривать двусмысленность.
Поскольку вообще невозможно доказать, что шаблон не может когда-либо удовлетворить constexpr
, для него не требуется никакой диагностики (но он плохо сформирован, поэтому компиляторы могут жаловаться вам, если могутдокажите это для данного случая).
Вы правы в том, что это не очень полезно, если вы хотите указать, что «эта функция должна только использоваться в постоянном выражении», но это не то, чтоэта формулировка нацелена на.
Редактировать: Чтобы уточнить, constexpr
для функций означает только "допустимо оценивать внутри константного выражения" (более точная формулировка здесь ), not "может оцениваться только во время компиляции" .Напротив, constexpr
переменные должны быть инициализированы с помощью константного выражения.
Другое редактирование: у нас есть точная формулировка для обсуждения, благодаря @JackAidley!
Есликонкретизированная шаблонная специализация шаблона функции constexpr не сможет удовлетворить требования для функции constexpr, спецификатор constexpr
игнорируется и специализация не является функцией constexpr.
Проблема в том, что«существует по крайней мере один набор аргументов, для которых функция может быть оценена на постоянной основе» - это часть «требований к функции constexpr».Следовательно, компиляторы не могут реализовать это предложение, поскольку невозможно доказать (в общем случае), существует ли такой набор для данной функции (или создания экземпляра шаблона функции).Вы должны либо запутать это требование, либо отказаться от этого аспекта.Похоже, комитет выбрал последнее.