标准库标头 <any> (C++17)学习

此头文件是通用工具库的一部分。类 any 描述一种可用于任何可复制构造类型的单个值的类型安全容器。

1) 类 any 的对象存储满足构造函数要求的任何类型的一个实例或为空,这被称为 any 类对象的状态。存储的实例被称作所含对象。若两个状态均为空,或均为非空且其所含对象等价,则两个状态等价。

2) 非成员 any_cast 函数提供对所含对象的类型安全访问。

鼓励实现避免小对象的动态分配,但这种优化仅可以应用于 std::is_nothrow_move_constructible 对其返回 true 的类型。

成员函数

(构造函数)

构造 any 对象
(公开成员函数)

operator=

赋值 any 对象
(公开成员函数)

(析构函数)

销毁 any 对象
(公开成员函数)
修改器

emplace

更改所含对象,直接构造新对象
(公开成员函数)

reset

销毁所含对象
(公开成员函数)

swap

交换两个 any 对象
(公开成员函数)
观察器

has_value

检查对象是否含有值
(公开成员函数)

type

返回所含值的 typeid
(公开成员函数)

非成员函数

std::swap(std::any)

(C++17)

特化 std::swap 算法
(函数)

any_cast

(C++17)

对所含对象的类型安全访问
(函数模板)

make_any

(C++17)

创建 any 对象
(函数模板)

辅助类

bad_any_cast

(C++17)

当类型不匹配时由按值返回形式的 any_cast 所抛出的异常
(类)

示例代码:

#include <any>
#include <complex>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

//https://zh.cppreference.com/w/cpp/utility/any


class Star
{
    std::string name;
    int id;

public:
    Star(std::string name, int id) : name{ name }, id{ id }
    {
        std::cout << "Star::Star(string, int)\n";
    }

    void print() const
    {
        std::cout << "Star{\"" << name << "\" : " << id << "};\n";
    }
};

int main()
{
    std::cout << std::boolalpha;

    // any 类型  any声明的变量可以修改变量的类型。 下面是int------> double------>bool 
    // type,  any_case example 
    std::any a = 1;
    std::cout << "a.type().name()=======" << a.type().name() << ": " << std::any_cast<int>(a) << '\n';
    a = 3.14;
    std::cout << "a.type().name()=======" << a.type().name() << ": " << std::any_cast<double>(a) << '\n';
    a = true;
    std::cout << "a.type().name()=======" << a.type().name() << ": " << std::any_cast<bool>(a) << '\n';

    // 有误的转型   bad_any_cast example
    try
    {
        //a = 3.1f;   //这个是正确的float类型
        a = 1;
        std::cout << std::any_cast<float>(a) << '\n';
    }
    catch (const std::bad_any_cast& e)
    {
        std::cout << "e.what() ======" << e.what() << '\n';
    }

    // 拥有值  has_value example
    a = 2;
    if (a.has_value())
        std::cout << "a.type().name()=======" << a.type().name() << ": " << std::any_cast<int>(a) << '\n';

    // 重置后,a就已经没有值了 reset example  
    a.reset();
    if (!a.has_value())
        std::cout << "没有值\n";

    // 指向所含数据的指针  a声明为整形
    a = 3;  
    int* i = std::any_cast<int>(&a);
    std::cout << *i << '\n';

    //make_any example
    auto a0 = std::make_any<std::string>("Hello, std::any!\n");
    auto a1 = std::make_any<std::complex<double>>(0.1, 2.3);

    std::cout << std::any_cast<std::string&>(a0);
    std::cout << std::any_cast<std::complex<double>&>(a1) << '\n';

    using lambda = std::function<void(void)>;

    // 把 lambda 放入 std::any。尝试 #1(失败)。
    std::any a2 = [] { std::cout << "Lambda #1.\n"; };
    std::cout << "a2.type() = \"" << a2.type().name() << "\"\n";

    // any_cast 转型到 <void(void)> 但实际类型不是
    // std::function ……,而是 ~ main::{lambda()#1},且它对
    // 每个 lambda 唯一。所以这会抛出……
    try
    {
        std::any_cast<lambda>(a2)();
    }
    catch (std::bad_any_cast const& ex)
    {
        std::cout << ex.what() << '\n';
    }

    // 将 lambda 放入 std::any 中。尝试 #2(成功)
    auto a3 = std::make_any<lambda>([] { std::cout << "Lambda #2.\n"; });
    std::cout << "a3.type() = \"" << a3.type().name() << "\"\n";
    std::any_cast<lambda>(a3)();

    //emplace example
    std::any celestial;
    // (1) emplace( Args&&... args );
    celestial.emplace<Star>("Procyon", 2943);
    const auto* star = std::any_cast<Star>(&celestial);
    star->print();

    std::any av;
    // (2) emplace( std::initializer_list<U> il, Args&&... args );
    av.emplace<std::vector<char>>({ 'C', '+', '+', '1', '7' } /* 无参数 */);
    std::cout << av.type().name() << '\n';
    const auto* va = std::any_cast<std::vector<char>>(&av);
    std::for_each(va->cbegin(), va->cend(), [](char const& c) { std::cout << c; });  //#include <algorithm>
    std::cout << '\n';

    //swap example
    std::any a5 = 5;
    std::any a6 = 6.3;
    std::cout << "a5.type().name()=======" << a5.type().name() << ": " << std::any_cast<int>(a5) << '\n';
    std::cout << "a6.type().name()=======" << a6.type().name() << ": " << std::any_cast<double>(a6) << '\n';
    a5.swap(a6);
    std::cout << "a5.type().name()=======" << a5.type().name() << ": " << std::any_cast<double>(a5) << '\n';
    std::cout << "a6.type().name()=======" << a6.type().name() << ": " << std::any_cast<int>(a6) << '\n';
}

运行结果:

参考:

 std::any - cppreference.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值