![](/img/trans.png)
[英]Using std::launder to “validate” non “pointer to object” pointer value since C++17
[英]std::launder alternative pre c++17
它就像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
题
std::launder
吗? 我猜不会。 std::launder
仅在c ++ 17中可用,如何在c ++ 14中实现上面的类? boost::optional
和std::experimental::optional
应该需要类似的功能还是使用编译器特定的魔法? 注意:很容易遗漏,类型被声明为union
。 这意味着T
构造函数实际上没有被调用。 参考: https : //gcc.godbolt.org/z/EVpfSN
不,你不能。 提出std::launder
的原因之一是std::optional
在C ++ 14中无法实现。 您可以参考此讨论以获取详细信息。
另一方面,您可以在没有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
的实现使用了这个想法 ,并没有实现constexpr
语义(您可以参考其源代码了解详细信息)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.