std::any和枚举类转换

编程入门 行业动态 更新时间:2024-10-17 02:49:43

<a href=https://www.elefans.com/category/jswz/34/1764904.html style=std::any和枚举类转换"/>

std::any和枚举类转换

一、std::any和enum class

在前面分析过std::any和enum class的初步应用,但是在实际应用 中,这两个之间在一起应用时还是要有些小细节需要注意。在程序的开发中,一般来说,不建议直接使用魔数来进行各种情况下的区别。毕竟时间长久后,这些魔数会变得不好理解甚至误解。同样,枚举类的出现导致直接使用枚举的不安全行为得到了控制,但也相应的出现了数据转换的问题。
对于std::any也是如此,它既然可以存储各种数据类型,就会有各种不同的情况出现。如果两者在一起使用,会出现一些具体的问题需要说明一下。

二、应用分析

1、枚举类的直接转换
枚举类和普通值的互转用得还是比较多的:

enum class K:int { k1 = 1, k2 };int a = 10;
K k = k(a);a = static_cast<int>(k);

这个还是比较简单的。
看一个稍微复杂的:

	#include <iostream>#include <type_traits>enum e1 {};enum class e2 {};enum class e3: unsigned {};enum class e4: int {};int main() {constexpr bool e1_t = std::is_same_v< std::underlying_type_t<e1>, int >;constexpr bool e2_t = std::is_same_v< std::underlying_type_t<e2>, int >;constexpr bool e3_t = std::is_same_v< std::underlying_type_t<e3>, int >;constexpr bool e4_t = std::is_same_v< std::underlying_type_t<e4>, int >;std::cout<< "underlying type for 'e1' is " << (e1_t ? "int" : "non-int") << '\n'<< "underlying type for 'e2' is " << (e2_t ? "int" : "non-int") << '\n'<< "underlying type for 'e3' is " << (e3_t ? "int" : "non-int") << '\n'<< "underlying type for 'e4' is " << (e4_t ? "int" : "non-int") << '\n';}

可能输出:

underlying type for 'e1' is non-int
underlying type for 'e2' is int
underlying type for 'e3' is non-int
underlying type for 'e4' is int

2、std::any的处理
一般来说把对象转成std::any直接赋值即可,而反之则需要使用std::any_cast():

std::any x = 10;
int v = std::any<int>(x);

3、枚举类通用转化
在上面的代码中对枚举进行了转换,将普通值转成枚举类还好说一些,直接调用构造函数即可,但反过来则比较麻烦,可以有一个比较通用的方式:

// print enum class
enum class K { k1 = 1, k2 };enum class T { t1, t2 };
template <typename T> auto print(T const v) -> typename std::underlying_type<T>::type {return static_cast<typename std::underlying_type<T>::type>(v);
}void printEnumClass() {auto k = K::k1;auto t = T::t2;std::cout << print(k) << std::endl;std::cout << print(t) << std::endl;
}

这里使用了std::underlying_type,不过不使用其也可以,直接用static_cast,就看各自的习惯了。

4、std::in_place_type的应用
std::underlying_type有几个相类似的函数,可以应用在std::optional和std::variant和std::any中,这里只是分析一下在std::any中的应用。先看一个例子:

#include <ccomplex>
#include <set>
void test_inplace() {//firststd::any a = 6;a = std::any{std::in_place_type<std::string>, "test"};std::any ab{std::in_place_type<long long>, 1};//secondstd::any com{std::complex{1.0, 3.0}};std::any com_d{std::in_place_type<std::complex<double>>, 2.0, 4.6};//thirdauto ret = [](int a, int b) { return true; };std::any any_ret{std::in_place_type<std::set<int, decltype(ret)>>, {3, 9}, ret};
}
int main()
{test_inplace();return 0;
}

简单的应用就不用介绍了,很容易就明白。上面的代码有几个应用 的不同方式,第一个是如果std::any在已经赋值其它类型后想再给予另外一种类型,就必须使用std::in_place_type来处理,比如上面代码的第一种;而第二种是对处理多个对象参数初始化的情况,也需要使用其来实现;第三种是可以使用std::in_place_type来实现初始化列表,在其后面跟上参数即可。
如果不想使用std::in_place_type,其它它还有一个更方便的函数make_any<>(),这个看来成为了标准库里处理的一个通行方法,一律make_xx一下,问题就解决了。另外,使用std::in_place_type,仍然会出现类似指针退化(数组转化成指针)的情况,这个需要注意。
5、两者共同使用
下面只给一个简单的例子就明白了。

 int preStatus = static_cast<int>(std::any_cast<K>(k));

三、总结

有些细节在应用开发时,可能还会费一些精神。其实重点不是这些细节多难,而是有时候儿遇到之时才会认真去追究这些细节的实现。实践出真知,诚不我欺。

更多推荐

std::any和枚举类转换

本文发布于:2023-12-05 20:39:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1665232.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:std

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!