__PRETTY_FUNCTION__
не стандартно.Таким образом, компилятор может реализовать его в разных местах (при синтаксическом анализе, при создании AST или при компоновке).
Если он должен быть реализован при синтаксическом анализе, то он может быть константным выражением (думаю, это то, чтолязг делает).Однако, если он реализован во время компоновки (то есть компилятор выдает для него символ, а компоновщик разрешит его), он не может быть константным выражением.
Я думаю, что GCC использует последний случай.
Обратите внимание, что в этом случае вы можете использовать их sizeof (), так как это const char[]
, если вам нужно вычислить длину строки констант во время компиляции.Поэтому замените выражение 3 на:
X<sizeof(__PRETTY_FUNCTION__) - 1> x;
, и оно прекрасно скомпилируется на обоих компиляторах.
РЕДАКТИРОВАТЬ: Как отметил Натан Оливер, похоже, что GCC рассматривает подпись __PRETTY_FUNCTION__
как static const char[]
, в то время как clang / visual studio рассматривает ее как static constexpr const char[]
.Это болезненная неприятность в GCC (не ошибка, поскольку она не является стандартной), и они, кажется, исправили ее в версии> 8.0.0.
В выражениях (1) и выражении (2), __PRETTY_FUNCTION__
уменьшается до const char*
(указатель постоянный, но ничего не скажешь о данных).Для меня выражение (2) может ничего не доказывать, поскольку нет никакой гарантии, что указатели должны быть равными с обеих сторон равенства, даже если они указывают на «одинаковое» содержимое.string_view
конструктор ожидает const char*
, поэтому все, кроме __PRETTY_FUNCTION__
, которое может распасться на const char*
, передало бы выражение (2).