template<typename T>
struct manual_lifetime {
manual_lifetime() noexcept = default;
~manual_lifetime() = default;
// Not copyable/movable
manual_lifetime(const manual_lifetime&) = delete;
manual_lifetime(manual_lifetime&&) = delete;
manual_lifetime& operator=(const manual_lifetime&) = delete;
manual_lifetime& operator=(manual_lifetime&&) = delete;
template<typename Factory>
requires
std::invocable<Factory&> &&
std::same_as<std::invoke_result_t<Factory&>, T>
T& construct_from(Factory factory) noexcept(std::is_nothrow_invocable_v<Factory&>) {
return *::new (static_cast<void*>(&storage)) T(factory());
}
void destroy() noexcept(std::is_nothrow_destructible_v<T>) {
std::destroy_at(std::launder(reinterpret_cast<T*>(&storage)));
}
T& get() & noexcept {
return *std::launder(reinterpret_cast<T*>(&storage));
}
private:
alignas(T) std::byte storage[sizeof(T)];
};
std::invocable 判断是否可调用
std::invoke_result_t<Factory&> 调用返回的类型
std::launder 将指针当成对应对象来解释
https://lewissbaker.github.io/2022/08/27/understanding-the-compiler-transform#introduction
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。