Ответ 1
Функция A constexpr
НЕ ДОЛЖНА быть определена до ее первого использования, однако результат любого вызова, сделанного до определения, не является постоянным выражением.
Источник: С++ Стандартная черновик n4296, раздел 5.20:
условное выражение
e
является выражением основной константы, если оценкаe
, следуя правилам абстрактной машины, не будет оценивать одно из следующих выражений:
this
, за исключением функцииconstexpr
или конструктораconstexpr
, который оценивается как частьe
;- вызов функции, отличной от конструктора
constexpr
для литерального класса, функцииconstexpr
или неявного вызова тривиального деструктора [Примечание: разрешение перегрузки применяется как обычный - конец примечания];- вызов функции undefined
constexpr
или конструктора undefinedconstexpr
;- ...
из проекта 3485 (раздел 5.19):
Условное выражение является выражением основной константы, если оно не включает одно из следующего в качестве потенциально оцениваемого подвыражения, но не рассматриваются подвыражения логических И, логических ИЛИ и условных операций, которые не оцениваются [Примечание: перегруженный оператор вызывает функцию. - конец примечания]:
this
[Примечание: при оценке константного выражения подстановка подстановки функций заменяет каждое вхождениеthis
в функции-членеconstexpr
указателем на объект класса. - конечная нота];- вызов функции, отличной от конструктора
constexpr
для функции literal илиconstexpr
[Примечание: разрешение перегрузки применяется как обычно - примечание конца);- вызов функции undefined
constexpr
или конструктора undefinedconstexpr
- ...
Пример int x2 = s. t();
в n2235 действительно стал действительным из-за изменений, внесенных до стандартизации. Однако constexpr int x2 = s. t();
остается ошибкой.