Исключения в шаблонных нетиповых аргументах

Стандарт C++17 гласит:

Шаблонный аргумент для нетипового шаблонного параметра должен быть преобразованным константным выражением...

в то время как

значение константного выражения не должно быть адресом

  • строковый литерал
  • подобъект
  • некоторые другие исключения...

Насколько я понимаю, логическое обоснование исключения строковых литералов заключается в том, что в зависимости от реализации могут возникнуть A<"abc"> в разных единицах перевода могут возникать разные экземпляры (так как строковые литералы имеют внутреннюю связь), или может быть так, что адреса строковых литералов определяются во время связывания (поскольку строковые литералы хранятся в некоторой специальной постоянной памяти).

Первый вопрос: верно ли мое понимание обоснования исключения строковых литералов?

И второй вопрос: в чем причина исключения подобъектов объектов со статической продолжительностью хранения? Я подозревал, что проблема может быть в выравнивании, но выравнивание выполняется во время компиляции, верно?

1 ответ

Основная идея состоит в том, что искаженное имя будет включать в себя (имя) символ, адрес которого берется. Для строкового литерала такого символа нет, поэтому вам придется включать сам литерал. Возможность указания подобъектов также потребует, чтобы в календари входили (возможно, несколько) неоднозначные имена типов:

struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {} d;

template<A*> struct X;
void f(X<(A*)(B*)&d>*);

Как обычно, стандарт избегает признания существования таких вещей, как искажение, но они сильно двигаются ими.

Другие вопросы по тегам