Я не могу видеть, как переинтерпретировать отлитые в этих или подобных случаях может быть любой отличаются от арифметических операторов
Это не является переносимым.
Возможно, вам известно о том, что ваш код вызывает неопределенное поведение, поскольку вы разыскиваете произвольный стрелок типа и, таким образом, нарушаете строгий псевдоним. Более того, поскольку C++ 14, операции, вызывающие неопределенное поведение, больше не являются постоянными выражениями, и поэтому они должны приводить к ошибке компилятора.
Что вы в основном пытаетесь сделать, это псевдоним объекта float
со встроенным значением glvalue. Первый шаг - получить это значение gl; второй - для преобразования lvalue-to-rvalue.
В C++ 14 первый шаг невозможно выполнить в постоянных выражениях. reinterpret_cast
явно запрещен. И бросает и из void*
, как static_cast<char const*>(static_cast<void const*>(&x))
, не работают либо (N3797, [expr.const]/2 *):
- преобразование из типа сортаvoid *
на объект указатель на тип;
Имейте в виду, что отливка с-стиль, как (char*)
сводится либо static_cast
или reinterpret_cast
, чьи ограничения перечислены выше. (unsigned*)&x
поэтому сводится к reinterpret_cast<unsigned*>(&x)
и не работает.
В C++ 11 отливка до void const*
, а затем до char const*
не представляет собой проблему (согласно стандарту, Clang по-прежнему жалуется на последние). Преобразование lvalue-rvalue является тем не менее:
преобразование значения lvalue-to-rvalue (4.1), если он не применяется к
- a glvalue интегрального или перечисляемого типа, который относится к энергонезависимому объекту const с предшествующей инициализацией, инициализированным константным выражением , или
- значение gl-значения буквального типа, которое относится к энергонезависимого объект, определенный с constexpr
, или, что относится к подобъекту такого объекта, или
- в glvalue буквального типа, который относится к энергонезависимому временному объекту, срок службы не закончился, инициализированным с постоянным выражением;
Первые две пули не могут применяться здесь; Также нет char
/unsigned
/etc. объект инициализировался ранее, и мы не определяли какой-либо такой объект с constexpr
.
Третий пуля не применяется. Если мы пишем
char ch = *(char const*)(void const*)&x;
мы не создаем char
объект в инициализаторе. Мы получаем доступное значение x
через значение gl типа char
и используем это значение для инициализации ch
.
Поэтому я бы сказал, что такое наложение невозможно в постоянных выражениях. Вы можете обойти это в некоторых реализациях с расслабленными правилами.
* Этот пункт является список, который начинается с чем-то вроде
условно-выражения является постоянным выражением ядра если не [...]
(Текст отличается от N3337 по N3797.)
Это также недопустимо в контекстах, не связанных с constexpr. Это просто неопределенное. Но это может быть сделано допустимым, и этого все равно не будет достаточно, чтобы сделать его constexpr-valid, поэтому вопрос остается в силе. – hvd
Почему вы хотите сделать это в 'constexpr',' constexpr' новая функция для злоупотребления? –
@ DavidRodríguez-dribeas - действительно. Я пытаюсь изучить границы некоторых возможностей C++ 11, это не настоящая необходимость. – nbubis