[英]C++: template function to retrieve value from an union
我正在編寫一個模板,以從可以容納不同數據類型的集合中獲取價值。 例如一個變體結構。 但是,當編譯器為其他類型的賦值生成代碼時,我會收到警告。 對於前
struct Variant
{
enum Type
{
_bool,
_int
};
Type type;
union VAL
{
bool bVal;
int nVal;
}val;
};
template <typename ValType>
void GetValue(Variant v, ValType val)
{
if(v.type == Variant::_bool)
{
val = v.val.bVal;
}
else if(v.type == Variant::_int)
{
val = v.val.nVal; // C4800
}
}
Variant v;
v.type = Variant::_bool;
v.val.bVal = true;
bool bVal(false);
GetValue(v, bVal);
警告:
warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
有人可以建議如何重寫模板以正確的方式獲得價值嗎?
在ValType === bool
GetValue
模板中, val
的類型為bool。 因此,行val = v.val.nVal;
導致警告。
為了為特殊類型提供特殊代碼,有模板特殊化。
您可以像這樣專門化功能模板
template<class T>
void GetValue(Variant v, T & val);
template<>
void GetValue<int>(Variant v, int & val)
{
if (v.type == Variant::_int)
val = v.val.nVal;
}
template <>
void GetValue<bool>(Variant v, bool & val)
{
if (v.type == Variant::_bool)
val = v.val.bVal;
}
注意: v.type
不能確定將調用哪個,而參數則可以。
首先,正如dyp在評論中已經建議的那樣,我建議您看一下Boost.Variant
。
就是說,您遇到的問題是,無論內部存儲什么類型,每個分支總是必須以您編寫它的方式進行編譯-而且其中一些分支可能沒有任何意義(如果您添加了數組還是其他POD類型?)Boost解決此問題的方法是要求用戶傳入函子,然后使用正確的類型調用該函子:
template <typename F>
void visit(Variant v, F visitor)
{
if(v.type == Variant::_bool) {
visitor(v.val.bVal);
}
else if(v.type == Variant::_int) {
visitor(v.val.nVal);
}
// etc.
}
因此,您只需編寫一個訪客:
struct get_bool {
void operator()(bool b) {
bVal = b;
}
template <typename OTHER>
void operator()(OTHER ) { }
bool& bVal;
};
並使用它:
bool bVal(false);
visit(v, get_bool{bVal});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.