gpt4 book ai didi

c++ - std::launder alternative pre c++17

转载 作者:可可西里 更新时间:2023-11-01 15:25:05 28 4
gpt4 key购买 nike

它类似于 std::optional,但不存储额外的 bool。用户必须确保只有在初始化后才能访问。

template<class T>
union FakeOptional { //Could be a normal struct in which case will need std::aligned storage object.
FakeOptional(){} //Does not construct T
template<class... Args>
void emplace(Args&&... args){
new(&t) T{std::forward<Args&&>(args)...};
}
void reset(){
t.~T();
}
operator bool() const {
return true;
}
constexpr const T* operator->() const {
return std::launder(&t);

}
constexpr T* operator->() {
return std::launder(&t);
}
T t;
};

如果您想知道为什么我需要这样一个晦涩的数据结构,请查看此处:https://gitlab.com/balki/linkedlist/tree/master

问题

  1. 可以忽略 std::launder 吗?我想不会。
  2. 由于std::launder仅在c++17中可用,如何在c++14中实现上述类? boost::optionalstd::experimental::optional 应该需要类似的功能,还是他们使用了编译器特定的魔法?

注意:容易漏掉,类型声明为union。这意味着 T 的构造函数实际上没有被调用。引用:https://gcc.godbolt.org/z/EVpfSN

最佳答案

不,你不能。提出 std::launder 的原因之一是 std::optional 在 C++14 中不可实现。可以引用this discussion了解详情。

另一方面,您可以在没有 constexpr 的情况下实现一个。这个想法是使用带有 reinterpret_cast 的缓冲区,因为 reinterpret_cast 的结果将始终引用新创建的对象(在 C++17 std::launder 仍然是必需的,但在 C++14 中这很好)。例如,

template<class T>
struct FakeOptional {
FakeOptional(){}
template<class... Args>
void emplace(Args&&... args){
new(&storage) T{std::forward<Args&&>(args)...};
}
void reset(){
reinterpret_cast<T*>(&storage)->~T();
}
operator bool() const {
return true;
}
const T* operator->() const {
return reinterpret_cast<const T*>(&storage);
}
T* operator->() {
return reinterpret_cast<T*>(&storage);
}
std::aligned_storage_t<sizeof(T), alignof(T)> storage;
};

boost::optional 的实现 uses this idea并且没有实现constexpr语义(可以引用它的source code了解详情)。

关于c++ - std::launder alternative pre c++17,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54259889/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com