- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想确认我是否正确使用 std::launder(...)
确保我正确理解它的用法。
我正在创建一个 Result<U,E>
在基于 Rust 实现的 C++ 中。
template <typename E>
class ResultStorage<void, E, std::enable_if_t<std::is_trivially_destructible_v<E>>> {
using type = typename std::aligned_storage<sizeof(E), alignof(E)>::type;
public:
explicit constexpr ResultStorage(const Ok<void>&) noexcept : tag_(ResultTag::OK) {}
explicit constexpr ResultStorage(const Ok<void>&&) noexcept : tag_(ResultTag::OK) {}
explicit constexpr ResultStorage(const Err<E>& err) noexcept(std::is_nothrow_copy_constructible<E>())
: tag_(ResultTag::ERR) {
new (&error_) E(err.get_error());
}
explicit constexpr ResultStorage(const Err<E>&& err) noexcept(std::is_nothrow_move_constructible<E>())
: tag_(ResultTag::ERR) {
new (&error_) E(std::move(err.get_error()));
}
~ResultStorage() = default;
[[nodiscard]] constexpr E& get_error() & noexcept {
assert_err(tag_);
return *std::launder(reinterpret_cast<E*>(&error_));
}
// Code omitted for brevity
private:
ResultTag tag_;
type error_;
template <typename Rv, typename Ev>
friend class result::Result;
};
在我使用的代码中
using type = typename std::aligned_storage<sizeof(E), alignof(E)>::type;
作为我的存储类型。我相信我需要使用
std::launder(...)
当我像这样从函数返回错误类型时:
[[nodiscard]] constexpr E& get_error() & noexcept {
assert_err(tag_);
return *std::launder(reinterpret_cast<E*>(&error_));
}
我相信我需要使用
std::launder(...)
的原因是因为传入的错误类型可能是一个结构体,可能带有
const
值那么看来,如果我不使用
std::launder(...)
然后在第一次初始化时,它将引用
const
成员值,如果我要重用这个分配的存储,它总是指初始
const
成员(member)值(value)。
std::launder
有一个初步的了解因此,对什么情况需要使用它的解释将不胜感激。我已经查看了这个函数的 cppreference,但仍然觉得它很神秘。
最佳答案
我不会冒险去猜测 std::launder
,但您的代码有另一个问题,解决它会使 std::launder
不再需要:
new (&error_) E(err.get_error());
(reinterpret_cast<E*>(&error_);
这是错误的,因为标准保证创建的对象实际上从
&error
开始。仅适用于标准布局类型。我知道这在实践中实际上并非如此的一种特殊情况是当您有多重继承时。
// class data member:
E* ptr = nullptr;
// then:
ptr = new (&error_) E(err.get_error());
并且只能使用
ptr
访问存储的对象。这也会使
std::launder
不再需要了。
关于c++ - 正确使用 std::launder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63002437/
我正在阅读 cppreference 并在 std::aligned_storage 的示例中有一个 vector/数组类的例子: template class static_vector {
我正在为 Game Boy Advance 使用 C++ 做一个有点不平凡的项目,而且,作为一个完全没有内存管理的有限平台,我试图避免调用 malloc和动态分配。为此,我实现了相当多的“就地多态容器
我想确认我是否正确使用 std::launder(...)确保我正确理解它的用法。 我正在创建一个 Result在基于 Rust 实现的 C++ 中。 template class ResultSt
考虑这段代码: void f(char * ptr) { auto int_ptr = reinterpret_cast(ptr); // (&i)); } void example_2()
考虑以下固定大小 vector 的简化且不完整的实现: template class Vec { T *start, *end; public: T& operator[](ssize_t i
P0137引入了函数模板 std::launder 并在有关 union 、生命周期和指针的部分中对标准进行了许多更改。 本文要解决的问题是什么?我必须注意的语言变化是什么?我们在洗钱做什么? 最佳答
std::launder 函数要求通过结果可访问的每个字节都可通过参数访问。 “可达”定义如下: A byte of storage is reachable through a pointer va
这是我不明白的示例部分: struct Y { int z; }; int main() { alignas(Y) std::byte s[sizeof(Y)]; Y *q =
当前标准草案(大概是 C++17)在 [basic.compound/4] 中说: [ Note: An array object and its first element are not poin
这个问题跟在这个 one 之后 让我们考虑这个示例代码: struct sso { union{ struct { char* ptr; char size_r
当前的标准草案(大概是 C++17)在 [basic.compound/4] 中说: [ Note: An array object and its first element are not poi
在 const_cast 之后修改一个 const 构造的对象是 UB(我相信是由于不断传播)。即使与 std::launder 结合使用,它仍然是 UB 吗? (哪个 AFAIK 阻止了一些优化,例
[1] 有没有添加p0593r6的情况转化为 C++20(第 6.7.2.11 节对象模型 [intro.object])制作 std::launder没有必要,在 C++17 中需要相同的用例 st
我想知道为什么 std::launder 是一个 constexpr 函数。有没有可以在编译时使用的用例? 最佳答案 因为绝对没有理由不这样做。它实际上只是对编译器具有一些特殊附加含义的恒等函数。它不
我必须使用不同版本的 clang 编译相同的代码。由于代码包含一些 c++17 功能,并非每个版本的 clang 都支持这些功能,因此我想在编译时检查它们是否受支持。据我所知,clang 的 feat
它类似于 std::optional,但不存储额外的 bool。用户必须确保只有在初始化后才能访问。 template union FakeOptional { //Could be a normal
对于 feature request的 a project of mine ,我想/有人建议我使用 std::launder 在 vector 中移动元素,其中元素只能移动可构造(未定义移动赋值运算符
考虑这个 union : union A{ int a; struct{ int b; } c; }; c和 a不是 layout-compatibles类型,因此无法读取
此问题是对 Is adding to a "char *" pointer UB, when it doesn't actually point to a char array? 的后续问题。 在 C
这个问题在这里已经有了答案: Does this really break strict-aliasing rules? (3 个答案) 关闭 5 年前。 以下例子来自std::aligned_st
我是一名优秀的程序员,十分优秀!