【C++】C++17中可以存储任意类型数据的对象——any类的使用与设计思想

目录

引言

any类的使用

构造

=号运算符重载

std::any::swap

std::any::has_value

std::any::type

std::any::reset

std::any_cast

any类的设计思想


个人主页:东洛的克莱斯韦克-优快云博客

C++专栏:C++_东洛的克莱斯韦克的博客-优快云博客

引言

        一提到存储任意类型,第一时间想到的可能就是STL容器,这种容器都是模板。但是,模板类在实例化对象是都要指定类型,例如std::vector<int> v 。那么模板实例化的对象存储的数据类型就是固定的。

        C++17提供了std::any类,头文件是<any>。any类实例化的对象可以存储任意类型的数据,本文会为大家介绍如何使用any类以及any类是如何实现的。

any类的使用

构造

any类最常用的构造

1.空构造        2.用任意类型数据构造        3.用any容器构造

    std::any a; //空构造
    std::any a1(43);  //任意类型数据构造
    std::any a2(a1);  //any容器构造

也可以用

### 关于 `std::any` 的介绍 `std::any` 是 C++17 中引入的一个模板,用于存储任何型的值。它提供了一种安全的方式来保存和检索不同型的对象,而无需知道具体型。通过使用 `std::any_cast` 函数可以提取存储对象。 以下是关于 `std::any` 的一些重要特性和用法: #### 1. 基本定义特性 `std::any` 可以存储任意类型的单个值或为空(不包含任何值)。如果尝试访问未设置的 `std::any` 对象,则会抛出异常 `std::bad_any_cast`[^4]。 #### 2. 创建赋值 可以通过直接初始化或者拷贝/移动语义来创建并赋值给 `std::any` 型变量。 ```cpp #include <iostream> #include <any> int main() { std::any a = 42; double b = 3.14; // 赋值操作 a = b; if (a.type() == typeid(double)) { std::cout << "Value of 'a' as double: " << std::any_cast<double>(a) << '\n'; } } ``` 上述代码展示了如何将不同型的数据存入 `std::any` 并通过 `typeid()` 和 `std::any_cast<T>()` 来判断以及获取其内部数据[^5]。 #### 3. 使用场景 当函数返回值可能有多种型时,`std::any` 提供了一个通用解决方案。例如,在某些情况下无法预知确切的结果型时可采用此方法替代传统的多态机制或其他复杂设计模式。 #### 4. 安全性考虑 由于每次都需要显式转换回原始型才能正常使用其中的内容,因此增加了程序的安全性——错误匹配将会引发运行期异常而不是编译失败[^6]。 --- ### 示例代码展示 下面给出一段完整的例子说明如何利用 `std::vector<std::any>` 存储混合型数组,并遍历打印它们各自的数值: ```cpp #include <iostream> #include <string> #include <vector> #include <any> #include <typeinfo> void print(const std::any& value){ try{ if(value.type()==typeid(int)){ std::cout<<std::any_cast<int>(value)<<'\n'; }else if(value.type()==typeid(std::string)){ std::cout<<std::any_cast<std::string>(value)<<'\n'; }else if(value.type()==typeid(double)){ std::cout<<std::any_cast<double>(value)<<'\n'; }// Add more types here... }catch(const std::bad_any_cast& ex){ std::cerr<<"Bad any cast exception caught:"<<ex.what()<<'\n'; } } int main(){ std::vector<std::any> vec={4,"hello",98.6,std::string{"world"}}; for(auto&& elem : vec){ print(elem); } return 0; } ``` 在这个例子中我们定义了一个名为 `print` 的辅助功能用来处理各种潜在输入形式;然后在一个向量里填充了一些异构元素并通过循环调用了该函数逐一显示出来[^7]。 ---
评论 64
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值