名稱空間
變體
操作

std::construct_at

來自 cppreference.com
< cpp‎ | 記憶體
 
 
記憶體管理庫
(僅作說明*)
未初始化記憶體演算法
(C++17)
(C++17)
(C++17)
construct_at
(C++20)
受約束的未初始化
記憶體演算法
C 庫

分配器
記憶體資源
垃圾回收支援
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
未初始化儲存
(直到 C++20*)
(直到 C++20*)
顯式生命週期管理
 
定義於標頭檔案 <memory>
template< class T, class... Args >
constexpr T* construct_at( T* location, Args&&... args );
(C++20 起)

在給定地址 location 處建立並初始化一個 T 物件,初始化引數為 args

等效於 if constexpr (std::is_array_v<T>)
    return ::new (voidify (*location)) T[1]();
else
    return ::new (voidify (*location)) T(std::forward<Args>(args)...);
,除了 construct_at 可用於常量表達式的求值中(C++26 前)

construct_at 在某個常量表達式 expr 的求值中被呼叫時,location 必須指向由 std::allocator<T>::allocate 獲取的儲存空間,或者是在 expr 的求值期間生命週期開始的物件。

僅當所有以下條件都滿足時,此過載才參與過載決議:

如果 std::is_array_v<T>truesizeof...(Args) 非零,則程式非良構。

目錄

[編輯] 引數

location - 指向將被構造 T 物件的未初始化儲存的指標
args... - 用於初始化的引數

[編輯] 返回值

location

[編輯] 示例

#include <bit>
#include <memory>
 
class S
{
    int x_;
    float y_;
    double z_;
public:
    constexpr S(int x, float y, double z) : x_{x}, y_{y}, z_{z} {}
    [[nodiscard("no side-effects!")]]
    constexpr bool operator==(const S&) const noexcept = default;
};
 
consteval bool test()
{
    alignas(S) unsigned char storage[sizeof(S)]{};
    S uninitialized = std::bit_cast<S>(storage);
    std::destroy_at(&uninitialized);
    S* ptr = std::construct_at(std::addressof(uninitialized), 42, 2.71f, 3.14);
    const bool res{*ptr == S{42, 2.71f, 3.14}};
    std::destroy_at(ptr);
    return res;
}
static_assert(test());
 
int main() {}

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 3436 C++20 construct_at 無法建立陣列型別的物件 可以值初始化有界陣列
LWG 3870 C++20 construct_at 可以建立 cv 限定型別的物件 只允許 cv 非限定型別

[編輯] 參閱

分配未初始化的儲存
(std::allocator<T> 的公開成員函式) [編輯]
[靜態]
在已分配的儲存中構造一個物件
(函式模板) [編輯]
銷燬給定地址處的物件
(函式模板) [編輯]
在給定地址建立物件
(演算法函式物件)[編輯]