C++万能容器 std::any

std::variant QVariant

中文标准库:any

初始化列表initializer_list使用any

any是一种很特殊的容器,它只能容纳一个元素,但这个元素可以是任意的类型,可以是基本数据类型(int,double,char,float...)也可以是复合数据类型(类、结构体)

1.构造

initializer_list使用any

#include <iostream>
//#include <initializer_list>
#include <vector>
#include <any>

int main()
{
	std::string a = "aa";
	std::vector<std::any>  vec{ 111,a,1.2f,"bbb" };
	const char* b = "aa";

	for (auto elem : vec)
	{
		int x = 0;
		//std::cout <<"vector type:" << elem.type().name() << std::endl;

		if (typeid(elem).name() == typeid(a).name())
		{
			std::cout << "string type:";
			std::cout << std::any_cast<std::string>(elem) << std::endl;  //进不来
		}
		if (elem.type().name() == typeid(a).name())
		{
			std::cout << "string type:";
			auto ret = std::any_cast<std::string>(elem);  //类型错误会抛出异常
			std::cout << ret << std::endl;
		}
		if (elem.type().name() == typeid(x).name())
		{
			std::cout << "int type:";
			x = std::any_cast<int>(elem);  //类型错误会抛出异常
			std::cout << x << std::endl;
		}
		if (elem.type().name() == typeid(b).name())
		{
			std::cout << "const char* type:";
			auto ret = std::any_cast<const char*>(elem);  //类型错误会抛出异常
			std::cout << ret << std::endl;
		}
	}
	return 0;
}

自定义any容器

#include <memory>
class MyAny
{
public:
    template <typename T>  //这里用模板函数不用模板类,因为如果是模板类,实例化一个MyAny对象就需要指定类型,这样做any就没有了意义,
    MyAny(T t):base(std::make_unique<Data<T>>(t)) {}
    template <typename T>
    T any_cast()
    {
        auto p = dynamic_cast<Data<T>*>(base.get());
        if (!p)
            throw "type is error\n";
        return p->value;
    }
private:
    class Base
    {
    public:
        virtual ~Base() {} // 基类是一个多态类,必须定义析构函数
    };
    template <typename T>
    class Data:public Base
    {
    public:
        Data(T t) :value(t) {}

        T value;
    };
    //Data data;  //派生的子类Data需要模板参数才能创建,所以这里必须是没有模板的基类
    std::unique_ptr<Base> base; //如果是模板函数,不知道存储的数据类型,就需要在MyAny类内部再定义一个模板基类Base
    //Base base;  //不能用普通对象,因为无法把类型从Base转换到Data,没法访问value
};

int main() 
{
    MyAny d(0);
    MyAny e = 'c';
    MyAny f = "test";

    auto ret0 = d.any_cast<double>(); // 这里的类型一定要一致,否则this指针为空
    auto ret1 = e.any_cast<char>();
    auto ret2 = f.any_cast<const char*>();
    auto ret3 = f.any_cast<char*>();  //throw error

    return 0;
}

转载:C++17any类,万能容器

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