通过转换在 c++/winrt 中取消装箱数值
Unbox numerical value in c++/winrt with conversion
有没有办法不考虑类型对数值进行拆箱?对于前。装箱 int
,然后拆箱 double
或 long long
(如果可以转换)。重点是能够从某种未知类型拆箱到已知类型(如果可以进行转换)。
现在它的行为是这样的:
winrt::Windows::Foundation::IInspectable boxed_value = winrt::box_value(30);
int i = winrt::unbox_value<int>(boxed_value); //OK
double d = winrt::unbox_value<double>(boxed_value); //Exception
我想要这样的东西:
winrt::Windows::Foundation::IInspectable boxed_value = winrt::box_value(30);
int i = unbox_value_with_conversion<int>(boxed_value); //OK
double d = unbox_value_with_conversion<double>(boxed_value); //OK
要实现一种无论类型如何对数值进行拆箱的方法,您可以尝试将自动类型转换包装到 unbox_value_with_conversion 方法中,以您提到的 int、double 和 long long 类型为例。
函数声明
template<class T>
T unbox_value_with_conversion(winrt::Windows::Foundation::IInspectable const& value);
函数定义
template<class T>
inline T MainPage::unbox_value_with_conversion(winrt::Windows::Foundation::IInspectable const& value)
{
T res{};
auto vv = value.as<winrt::Windows::Foundation::IPropertyValue>();
if (vv.Type() == winrt::Windows::Foundation::PropertyType::Int32)
{
int32_t tt = vv.as<int32_t>();
res = (T)tt;
return res;
}
if (vv.Type() == winrt::Windows::Foundation::PropertyType::Double)
{
double dd = vv.as<double>();
res = (T)dd;
return res;
}
if (vv.Type() == winrt::Windows::Foundation::PropertyType::Int64)
{
long long llong = vv.as<long long>();
res = (T)llong;
return res;
}
return T();
}
类型转换
winrt::Windows::Foundation::IInspectable boxed_value1 = winrt::box_value(30);
double dd1 = unbox_value_with_conversion<double>(boxed_value1);
long long llong1= unbox_value_with_conversion<long long>(boxed_value1);
如果您不知道(或不关心)哪种类型的值被装箱,IReference<T>
使用起来不会很有趣。链接一堆 unbox_value/unbox_value_or
调用将引发一系列 QueryInterface
调用,这是一种非常低效的方法。更好的方法是使用 IPropertyValue。它已经执行标量转换,并处理溢出等错误。
winrt::Windows::Foundation::IInspectable boxed_value = winrt::box_value(30);
int i = boxed_value.as<winrt::Windows::Foundation::IPropertyValue>().GetInt32();
double d = boxed_value.as<winrt::Windows::Foundation::IPropertyValue>().GetDouble();
如果您愿意,为您的 unbox_value_with_conversion
.
提供模板专业化应该是一个简单的(如果稍微 repetitive/tedious)练习
template <typename T>
T unbox_value_with_conversion(winrt::Windows::Foundation::IInspectable const& value)
{
return winrt::unbox_value<T>(value);
}
template <>
int32_t unbox_value_with_conversion<int32_t>(winrt::Windows::Foundation::IInspectable const& value)
{
return value.as<winrt::Windows::Foundation::IPropertyValue>().GetInt32();
}
// Rest of specializations...
有没有办法不考虑类型对数值进行拆箱?对于前。装箱 int
,然后拆箱 double
或 long long
(如果可以转换)。重点是能够从某种未知类型拆箱到已知类型(如果可以进行转换)。
现在它的行为是这样的:
winrt::Windows::Foundation::IInspectable boxed_value = winrt::box_value(30);
int i = winrt::unbox_value<int>(boxed_value); //OK
double d = winrt::unbox_value<double>(boxed_value); //Exception
我想要这样的东西:
winrt::Windows::Foundation::IInspectable boxed_value = winrt::box_value(30);
int i = unbox_value_with_conversion<int>(boxed_value); //OK
double d = unbox_value_with_conversion<double>(boxed_value); //OK
要实现一种无论类型如何对数值进行拆箱的方法,您可以尝试将自动类型转换包装到 unbox_value_with_conversion 方法中,以您提到的 int、double 和 long long 类型为例。
函数声明
template<class T>
T unbox_value_with_conversion(winrt::Windows::Foundation::IInspectable const& value);
函数定义
template<class T>
inline T MainPage::unbox_value_with_conversion(winrt::Windows::Foundation::IInspectable const& value)
{
T res{};
auto vv = value.as<winrt::Windows::Foundation::IPropertyValue>();
if (vv.Type() == winrt::Windows::Foundation::PropertyType::Int32)
{
int32_t tt = vv.as<int32_t>();
res = (T)tt;
return res;
}
if (vv.Type() == winrt::Windows::Foundation::PropertyType::Double)
{
double dd = vv.as<double>();
res = (T)dd;
return res;
}
if (vv.Type() == winrt::Windows::Foundation::PropertyType::Int64)
{
long long llong = vv.as<long long>();
res = (T)llong;
return res;
}
return T();
}
类型转换
winrt::Windows::Foundation::IInspectable boxed_value1 = winrt::box_value(30);
double dd1 = unbox_value_with_conversion<double>(boxed_value1);
long long llong1= unbox_value_with_conversion<long long>(boxed_value1);
如果您不知道(或不关心)哪种类型的值被装箱,IReference<T>
使用起来不会很有趣。链接一堆 unbox_value/unbox_value_or
调用将引发一系列 QueryInterface
调用,这是一种非常低效的方法。更好的方法是使用 IPropertyValue。它已经执行标量转换,并处理溢出等错误。
winrt::Windows::Foundation::IInspectable boxed_value = winrt::box_value(30);
int i = boxed_value.as<winrt::Windows::Foundation::IPropertyValue>().GetInt32();
double d = boxed_value.as<winrt::Windows::Foundation::IPropertyValue>().GetDouble();
如果您愿意,为您的 unbox_value_with_conversion
.
template <typename T>
T unbox_value_with_conversion(winrt::Windows::Foundation::IInspectable const& value)
{
return winrt::unbox_value<T>(value);
}
template <>
int32_t unbox_value_with_conversion<int32_t>(winrt::Windows::Foundation::IInspectable const& value)
{
return value.as<winrt::Windows::Foundation::IPropertyValue>().GetInt32();
}
// Rest of specializations...