std::any

一、简介

std::any 可以储存任何可拷贝构造可销毁的类型的对象。

struct test
{
    test(int a,int b){}
};

int main(int argc, char *argv[])
{
    std::any a = 1;
    qDebug() << a.type().name();
    a = 3.14;
    qDebug() << a.type().name();
    a = true;
    qDebug() << a.type().name();
    a = test(1,2);
    qDebug() << a.type().name();
}

QObject 类型是不可拷贝的,直接将此类对象赋给 std::any 就会报错:

要把 QObject 赋给 std::any 应该赋指针:

二、相关函数

1、std::any_cast

在类型匹配的情况下,从 std::any 中获取存储的值,并将其转换为目标类型。

int main(int argc, char *argv[])
{
    std::any storage = 3.14;

    double d = std::any_cast<double>(storage);
    qDebug() << d;

    double* ptr = std::any_cast<double>(&storage);
    if (ptr)
    {
        qDebug() << *ptr;
    }
}

要注意如果类型不匹配会抛出 std::bad_any_cast 异常。

2、std::make_any

在运行时构建 std::any 类型的对象,并以推导模板参数的方式自动将输入参数转换为 std::any

这是两种方式:

std::any val = std::make_any<int>(23);
std::any val = 23;

二者的区别:

  • std::make_any<int>(23):使用 std::make_any 函数并指定模板参数为 int,通过调用 int 类型的构造函数创建一个临时的 int 对象,然后将该对象存储在 std::any 中。
  • std::any val = 23:直接将整数值 23 赋给 std::any 变量 val,此时编译器会自动推导出 std::any 对象的类型,并调用相应的构造函数来存储该值。

两者的区别在于对象的构造方式。使用 std::make_any 可以显式指定对象的类型,并通过调用构造函数来创建对象。

3、std::any::emplace

它是 std::any 成员函数,用于在 std::any 中就地构造存储的对象。

它可以在运行时指定对象的类型,并通过提供构造函数的参数,在 std::any 中构造出一个新的对象。

与直接赋值相比更加显示。

int main(int argc, char *argv[])
{
    std::any storage1 = 2.2;
    storage1 = 23;
    qDebug()<<storage1.type().name();   //int

    std::any storage2 = 2.2;
    storage2.emplace<qint8>(23);
    qDebug()<<storage2.type().name();   //signed char
}

4、std::any::has_value

std::any 的成员函数,用于检查 std::any 对象是否存储了一个值。

int main(int argc, char *argv[])
{
    std::any storage;
    qDebug() << storage.has_value(); // false
    storage = 42;
    qDebug() << storage.has_value() ; // true
}

5、std::any::reset

std::any 的成员函数,用于将 std::any 对象重置为空,释放其持有的值。

int main(int argc, char *argv[])
{
    std::any storage = 42;
    qDebug() << storage.has_value(); // true
    storage.reset();
    qDebug() << storage.has_value(); // false
}

6、std::any::type

std::any 的成员函数,如果对象非空则返回 std::any 对象的 typeidstd::type_info),空则返回 typeid(void)