QVariant,std::variant,std::any,std::optional,std::visit,union

一、Qt中的QVariant

Qt中的QVariant

QVariant和std::any有些类似,std::variant更像是std::any的一个子集

二、C++标准库中的std::variant(C++17)

QVariant和std::variant序列化与反序列化。(序列化就是把程序数据转换为可以传输或者写入文件的数据)

转载:最常用的两种C++序列化方案

中文标准库:std::variant

std::variant模板参数列表中如果包含没有默认构造函数的类型,可以使用std::monostate消除错误,例如std::variant<std::monostate, NoDefConstr> myVar

std::variant可以继承,例如class sub: public std::variant<int, float>

std::variant抛出异常类型为std::bad_variant_access

std::visit是用来操作std::variant的转载:C++17之std::visit

点击查看代码
#include <variant>
#include <string>
#include <vector>

int main()
{
    std::variant<int, int, int, float, float, std::string> var1;
    //var1 = 2.0f;  //错误,variant模板初始化有多个float,不知道是给第几个float赋值
    std::variant<int, int, float, float, char, char> var11{ std::in_place_index<3>,2 }; // 初始化为第三个类型
    var1.emplace<1>(2.0f); //正确,指定具体第几个类型,会强制类型转换
    auto index1 = var1.index(); // 1
    var1.emplace<5>("test");    //正确
    //var1.emplace<2>("test");  //错误
    //var1.emplace<int>(2);     //错误

    std::variant<int, float,char> var2;
    var2.emplace<int>(2); // 没有多个int类型时才可以这样赋值
    var2 = 2.0f;
    var2 = 3.0f; // 覆盖前面的值
    var2 = 'x';  // 覆盖前面的值
    auto index2 = var2.index(); // 此时var2的值为'x',是var2的第2个类型(从0开始)
    //auto ret1 = std::get<1>(var2);   //抛出异常,因为var2的值为'x'是第2个类型
    //auto ret2 = std::get<int>(var2); //抛出异常,var2值的类型为char
    auto ret1 = std::get<2>(var2);     // ret1 = 'x'
    auto ret2 = std::get<char>(var2);  // ret2 = 'x'

    // 注意get_if的参数必须为指针
    auto ret3 = std::get_if<int>(&var2);  // 获取失败返回nullptr
    auto ret4 = std::get_if<char>(&var2); // 获取成功返回char*

    std::vector<std::variant<int,float,char>> vec;
    vec.emplace_back(2);
    vec.emplace_back(2.0f);
    vec.emplace_back('x');
    //vec.emplace_back("xxx");  //错误,因为variant中没有"xxx"的类型

    int test = 0;
    return 0;
}

三、C++标准库中的std::any(C++17)

std::any

简单地说,std::variant 只能存放指定类型(模板初始化列表中的类型)的对象,而 std::any 可以存放任意(合法的)类型的对象。

四、C++标准库中的std::optional(C++17)

点击查看代码
#include <iostream>
#include <optional>
#include <string>

// convert string to int if possible:
std::optional<int> asInt(const std::string& s)
{
    try
    {
        return std::stoi(s);
    }
    catch (...)
    {
        return std::nullopt;
    }
}
int main()
{
    for (auto s : { "42", " 077", "hello", "0x33" })
    {
        // convert s to int and use the result if possible:
        std::optional<int> oi = asInt(s);
        if (oi) {
            std::cout << "convert '" << s << "' to int: " << *oi << "\n";
        }
        else {
            std::cout << "can't convert '" << s << "' to int\n";
        }
    }
}

中文标准库:optional

转载C++17之std::optional

std::pair<T,bool>std::option的联系

五、 union

union和std::variant有些类似,在C++程序中一般很少用到

C语言共用体union

posted @ 2021-09-24 11:16  滴哒哒哒  阅读(1108)  评论(0编辑  收藏  举报