我正在撰寫一個變體類(是的,我知道 std::variant,它只是為了好玩),這就是我目前所擁有的
template<typename First, typename... Rest>
union Variant<First, Rest...>
{
template<size_t N>
using Types = typename Type<N, First, Rest...>::_Type;
First first;
Variant<Rest...> rest;
uint16_t activeIndex;
template<size_t N>
Types<N>& get()
{
}
};
Type 結構體只允許我找到第 n 個元素的型別。我知道工會的所有成員都在同一個記憶體地址,所以我可以
return *(Types<N>*)&first
在 get 函式中?這是安全的嗎?或者有其他方法可以做到這一點。任何幫助,將不勝感激。
uj5u.com熱心網友回復:
您本質上想知道的是操作是否:
*(Types<N>*)&first
堅持嚴格的別名。答案是肯定的,只要回傳的型別Types<N>是兼容型別:
型別 T 和 U 是兼容的,如果它們是相同的型別(相同的名稱或由 typedef 引入的別名)
在您的示例中,我猜測這是通過說必須使用相同型別設定和檢索值來以某種方式傳遞給用戶的。如果是這種情況并且用戶遵守此規則,則它是安全的。
如果你想超越,你可以看看std::variant. 如果您嘗試檢索未正確設定的值,該std::variant::get函式實際上會拋出。為了達到這個目的,你可以考慮使用相反的方法Types<N>來獲取索引,并在設定時存盤它。然后檢查這是否是您在使用時使用的索引get,如果它們不相同,則拋出。
uj5u.com熱心網友回復:
與直接使用地址型別轉換相比,另一種方法是使用遞回。
為了減少遞回的深度,可以使用多個if constexpr分支來提前停止遞回。
template<size_t N>
Types<N>& get() const {
if constexpr (N == 0)
return first;
else if constexpr (N == 1)
return rest.first;
else if constexpr (N == 2)
return rest.rest.first;
else
return rest.rest.rest.template get<N - 3>();
}
演示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/397870.html
