Компилятор ожидает параметр в этом контексте, потому что он должен оценить полный (перегруженный шаблоном) тип функции.Учитывая реализацию pred, любое значение будет работать в этом месте.Здесь он связывает тип шаблона параметра f с аргументом.Компилятор g ++, похоже, делает упрощающее предположение, что функция шаблона constexpr
будет каким-то образом изменена любыми параметрами, если только они не являются const
, что, как вы продемонстрировали, и clang согласен, не обязательно так.
Все сводится к тому, как глубоко внутри реализации функции компилятор помечает функцию как неконстантную из-за неконстантного вклада в возвращаемое значение.
Тогда возникает вопросо том, является ли функция созданной и требует ли компилятор фактической компиляции кода по сравнению с выполнением синтаксического анализа шаблона, который, по крайней мере с g ++, представляется другим уровнем компиляции.
Затем я перешел к стандарту, и они любезнопозволить составителю компилятора сделать именно это упрощающее предположение, и создание экземпляра функции шаблона должно работать только для f<const T>
или f <const T&>
функции constexpr`: каждый из ее параметров должен быть LiteralType
Так шаблон кодадолжен скомпилироваться, но потерпеть неудачу, если создан с неконстантным T.