Ответ 1
Я не вижу, как реинтерпрет в этом или подобных случаях может быть любым отличной от арифметических операторов
Он не переносится.
Вероятно, вам известно о том, что ваш код вызывает поведение undefined, так как вы разыскиваете строковый указатель типа и, таким образом, нарушаете строгий псевдоним. Более того, поскольку С++ 14, операции, вызывающие поведение undefined, больше не являются постоянными выражениями и, следовательно, должны приводить к ошибке компилятора.
То, что вы в основном пытаетесь сделать, это псевдоним объекта float
со встроенным значением glvalue. Первый шаг - получить это значение gl; второй для выполнения преобразования lvalue-rvalue.
В С++ 14 первый шаг невозможно выполнить в постоянных выражениях. reinterpret_cast
явно запрещен. И отбрасывается в void*
и void*
, например static_cast<char const*>(static_cast<void const*>(&x))
, также не работают (N3797, [expr.const]/2 *):
- преобразование из типа cv
void *
в тип указателя к объекту;
Имейте в виду, что c-стиль, подобный (char*)
, сводится к static_cast
или reinterpret_cast
, ограничения которого перечислены выше. (unsigned*)&x
поэтому сводится к reinterpret_cast<unsigned*>(&x)
и не работает.
В С++ 11 приведение к void const*
, а затем к char const*
не представляет проблемы (согласно стандарту, Clang все еще жалуется на последнее). Преобразование lvalue-to-rvalue является тем не менее:
преобразование lvalue-to-rvalue (4.1), если оно не применяется к glvalue интегрального или перечисляемого типа, который относится к энергонезависимой const с предыдущей инициализацией, инициализированной постоянное выражение, или
- значение glvalue типа literal, которое ссылается на энергонезависимый объект, определенный с помощьюconstexpr
, или который ссылается на под-объект такого объекта, или
- значение glvalate типа, которое относится к энергонезависимому временному объекту, срок службы которого не завершено, инициализировано постоянным выражением;
Первые две пули не могут применяться здесь; Также не существует char
/unsigned
/etc. объект инициализировался ранее, и мы не определяли какой-либо такой объект с помощью constexpr
.
Третий пуля не применяется. Если мы напишем
char ch = *(char const*)(void const*)&x;
мы не создаем объект char
в инициализаторе. Мы получаем доступное значение x
через glvalue типа char
и используем это значение для инициализации ch
.
Поэтому я бы сказал, что такое наложение невозможно в постоянных выражениях. Вы можете обойти это в некоторых реализациях с непринужденными правилами.
* Абзац - это список, начинающийся с чего-то вроде
Условное выражение является выражением основной константы, если только [...]
(текст отличается от N3337 по N3797.)