std::start_lifetime_as, std::start_lifetime_as_array
Материал из cppreference.com
<tbody>
</tbody>
| Определено в заголовочном файле <memory>
|
||
| start_lifetime_as |
||
template< class T > T* start_lifetime_as( void* p ) noexcept; |
(1) | (начиная с C++23) |
template< class T > const T* start_lifetime_as( const void* p ) noexcept; |
(2) | (начиная с C++23) |
template< class T > volatile T* start_lifetime_as( volatile void* p ) noexcept; |
(3) | (начиная с C++23) |
template< class T > const volatile T* start_lifetime_as( const volatile void* p ) noexcept; |
(4) | (начиная с C++23) |
| start_lifetime_as_array |
||
template< class T > T* start_lifetime_as_array( void* p, std::size_t n ) noexcept; |
(5) | (начиная с C++23) |
template< class T > const T* start_lifetime_as_array( const void* p, std::size_t n ) noexcept; |
(6) | (начиная с C++23) |
template< class T > volatile T* start_lifetime_as_array( volatile void* p, std::size_t n ) noexcept; |
(7) | (начиная с C++23) |
template< class T > const volatile T* start_lifetime_as_array( const volatile void* p, std::size_t n ) noexcept; |
(8) | (начиная с C++23) |
1-4) Неявно создаёт полный объект типа
T (чей адрес p) и вложенные в него объекты. Значение каждого созданного объекта obj, который является TriviallyCopyable типа U, определяется так же, как и для вызова std::bit_cast<U>(E) за исключением того, что доступ к хранилищу фактически не осуществляется, где E это левостороннее значение типа U, обозначающее obj. Иначе значения таких созданных объектов не указаны.
Tдолжен быть ImplicitLifetimeType и должен быть полным типом, иначе программа некорректна.- Поведение не определено, если:
[p,(char*)p + sizeof(T))не обозначает область выделенного хранилища, которая является подмножеством области хранилища, достижимой черезp, или- область не выровнена надлежащим образом для
T.
- Обратите внимание, что неуказанное значение может быть неопределённым.
5-8) Неявно создаёт массив элементов типа
T и длиной n. Если быть точным, если n > 0 равно true, это эквивалентно std::start_lifetime_as<U>(p), где U это тип "массив из n типа T". Иначе функция не имеет никакого эффекта.
Tдолжен быть полным типом, иначе программа будет некорректной.- Поведение не определено, если:
- Ненулевой
pне выровнен надлежащим образом для массива типаTили n <= std::size_t(-1) / sizeof(T)равноfalse, илиn > 0и[(char*)p,(char*)p + (n * sizeof(T)))не обозначают область выделенного хранилища, которая является подмножеством области хранения, доступной черезp.
- Ненулевой
Параметры
| p | — | адрес области, состоящей из объектов |
| n | — | количество создаваемых элементов массива |
Возвращаемое значение
1-4) Указатель на полный объект, как описано выше.
5-8) Указатель на первый элемент созданного массива, если он есть; иначе указатель, который при сравнении равен
p.Примечание
new (void_ptr) unsigned char[size] или new (void_ptr) std::byte[size] работает как нетипизированная версия std::start_lifetime_as, но не сохраняет представление объекта.
std::start_lifetime_as обрабатывает типы, не являющиеся массивами, а также массивы с известной границей, а std::start_lifetime_as_array обрабатывает массивы с неизвестной границей.
| Макрос Тестирования функциональности | Значение | Стандарт | Функциональность |
|---|---|---|---|
__cpp_lib_start_lifetime_as |
202207L |
(C++23) | Явное управление временем жизни |
Пример
Запустить этот код
#include <complex>
#include <iostream>
#include <iterator>
#include <memory>
int main()
{
alignas(std::complex<float>) unsigned char network_data[sizeof(std::complex<float>)]{
0xcd, 0xcc, 0xcc, 0x3d, 0xcd, 0xcc, 0x4c, 0x3e
}
// auto d = *reinterpret_cast<std::complex<float>*>(network_data);
// std::cout << d << '\n'; // Неопределённое поведение: network_data не указывает
// на complex<float>
// auto d = *std::launder(reinterpret_cast<std::complex<float>*>(network_data));
// std::cout << d << '\n'; // Возможно неопределённое поведение, связанное с CWG1997:
// неявно созданный complex<float> может содержать неопределённое значение
auto d = *std::start_lifetime_as<std::complex<float>>(network_data);
std::cout << d << '\n'; // OK
}
Возможный вывод:
(0.1,0.2)
Ссылки
- C++23 стандарт (ISO/IEC 14882:2023):
- 20.2.6 Явное управление временем жизни [obj.lifetime]
Смотрите также
(C++20) |
переинтерпретирует объектное представление одного типа как другого (шаблон функции) |
(C++20) |
преобразует span в представление, состоящее из образующих его байтов (шаблон функции) |