Результат выражения static_cast<T>(v) - это результат преобразования выражения v в тип T. Если это ссылочный тип lvalue или ссылка rvalue на тип функции, результатом будет lvalue; если это ссылка rvalue на тип объекта, результатом будет xvalue; в противном случае результатом будет prvalue. Оператор не должен . T T static_cast cast away constness
- Значение типа «cv1 B», где B это тип класса, может быть приведен к типу «ссылка на cv2 D», где D класс derived от B, если cv2 одно и то же резюме-квалификации , как, или больше резюме , чем-квалификации, cv1. Если B это виртуальный базовый класс D или базовый класс виртуального базового класса D, или если не существует допустимого стандартного преобразования из «указателя на D» в «указатель на B» ([conv.ptr]), программа имеет неправильный формат. Значение xvalue типа «cv1 B» может быть приведено к типу «ссылка rvalue на cv2 D» с теми же ограничениями, что и для lvalue типа «cv1 B». Если объект типа «cv1 B» на самом деле является подобъектом базового класса объекта типа D, результат относится к включающему объекту типа D. В противном случае поведение не определено. [ Example:
struct B { };
struct D : public B { };
D d;
B &br = d;
static_cast<D&>(br); // produces lvalue to the original d object
— end example ]
Lvalue типа «cv1 T1» может быть приведено к типу «ссылка rvalue на cv2 T2», если «cv2 T2» находится reference-compatible с «cv1 T1». Если значение не является битовым полем, результат относится к объекту или его подобъекту указанного базового класса; в противном случае, lvalue-to-rvalue conversion применяется к битовому полю, а результирующее значение prvalue используется как expressionзначение static_cast для оставшейся части этого раздела. Если T2 - inaccessible или ambiguous базовый класс T1, программа, которая требует такого приведения, плохо сформирована.
Выражение e может быть явно преобразовано в тип, T если существует implicit conversion sequence от e до Tили если разрешение перегрузки для direct-initialization объекта или ссылки типа T from e найдет хотя бы одну жизнеспособную функцию ([over.match.viable]). Если T это ссылочный тип, эффект такой же, как при объявлении и инициализации.
T t(e);
для какой-то придуманной временной переменной t ([dcl.init]), а затем использовать временную переменную как результат преобразования. В противном случае объект результата инициализируется напрямую из e. [ Note: Преобразование неправильно сформировано при попытке преобразовать выражение типа класса в недоступный или неоднозначный базовый класс. ] — end note
В противном случае static_cast будет выполнено одно из преобразований, перечисленных ниже. Никакое другое преобразование не должно выполняться явно с использованием файла static_cast.
Любое выражение может быть явно преобразовано в тип cv void, и в этом случае оно становится discarded-value expression. [ Note: Однако, если значение находится в a temporary object, деструктор для этого объекта не выполняется до обычного времени, а значение объекта сохраняется для выполнения деструктора. ] — end note
Обратный любой , standard conversion sequence не содержащий lvalue-to-rvalue, array-to-pointer, function-to-pointer, null pointer, null member pointer, boolean, или function pointer преобразования, может быть выполнены с использованием явно static_cast. Программа плохо сформирована, если она используется static_cast для выполнения обратной неверной стандартной последовательности преобразования. [ Example:
struct B { }; struct D : private B { }; void f() { static_cast<D*>((B*)0); // error: B is a private base of D static_cast<int B::*>((int D::*)0); // error: B is a private base of D }
— end example ]
lvalue-to-rvalue, array-to-pointerИ function-to-pointer преобразования применяются в операнд. На такой static_cast объект действует ограничение, которое не предусмотрено явным преобразованием cast away constness, а также следующие дополнительные правила для конкретных случаев:
Значение a scoped enumeration type можно явно преобразовать в целочисленный тип. Когда этот тип равен cv bool, результирующее значение будет, false если исходное значение равно нулю и true для всех остальных значений. Для остальных целочисленных типов значение не изменяется, если исходное значение может быть представлено указанным типом. В противном случае результирующее значение не указано. Значение типа перечисления с заданной областью также может быть явно преобразовано в тип с плавающей запятой; результат такой же, как и при преобразовании исходного значения в тип с плавающей запятой.
Значение целочисленного или перечислимого типа может быть явно преобразовано в полный перечисляемый тип. Значение не изменяется, если исходное значение находится в диапазоне значений перечисления ([dcl.enum]). В противном случае поведение не определено. Значение типа с плавающей запятой также можно явно преобразовать в тип перечисления. Результирующее значение совпадает с преобразованием исходного значения в базовый тип enumeration ([conv.fpint]), а затем в тип перечисления.
Prvalue типа «указатель на cv1 B», где B является типом класса, может быть преобразовано в prvalue типа «указатель на cv2 D», где D - это класс derived из B, если cv2 это такая же квалификация cv или более высокая квалификация, чем, cv1. Если B это виртуальный базовый класс D или базовый класс виртуального базового класса D, или если не существует допустимого стандартного преобразования из «указателя на D» в «указатель на B» ([conv.ptr]), программа имеет неправильный формат. null pointer value Преобразуется в значение указателя нулевого типа назначения. Если prvalue типа «указатель на cv1 B» указывает на, B который на самом деле является подобъектом объекта типа D, результирующий указатель указывает на включающий объект типа D. В противном случае поведение не определено.
Prvalue типа «указатель на член D типа cv1 T» может быть преобразован в prvalue типа «указатель на член B типа cv2 T», где B равно a base class of D, если cv2 это такая же квалификация cv или более высокая квалификация cv, чем, cv1.72 Если не существует допустимого стандартного преобразования из «указателя на член B типа T» в «указатель на член D типа T» ([conv.mem]), программа сформирована неправильно. null member pointer value Преобразуются в значение указателя члена нуля типа назначения. Если класс B содержит исходный член или является базовым или производным классом класса, содержащего исходный член, результирующий указатель на член указывает на исходный член. В противном случае поведение не определено. [ Note: Хотя класс B не обязательно должен содержать исходный член, динамический тип объекта, с которым выполняется косвенное обращение через указатель на член, должен содержать исходный член; см [expr.mptr.oper]. ] — end note
Prvalue типа «указатель cv1 void» может быть преобразовано в prvalue типа «указатель на cv2 T», где T это тип объекта , и cv2 это тот же CV-квалификацию или более CV-квалификацию , чем, cv1. Если исходное значение указателя представляет собой адрес A байта в памяти и A не удовлетворяет требованию выравнивания T, то результирующее значение указателя не указано. В противном случае, если значение исходных точки указателя на объект a, и есть объект b типа T (без учета CV-квалификация) , который pointer-interconvertible с a, результатом является указателем b. В противном случае значение указателя не изменится при преобразовании. [ Example:
T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
bool b = p1 == p2; // b will have the value true.
— end example ]