![](/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.