现代C++学习——C++17动态类型any与类型擦拭

any关键字

any 是 c++17 的语法,用处是类似像 python 一样进行类型擦拭。比如下面的代码,a 即可以是 int,也可以后面赋值为 string。

#include <iostream>
#include <string>
#include <any>

int main() {
    std::any a = 1;
    std::cout << std::any_cast<int>(a) << '\n';

    a = std::string("hello, world!");
    std::cout << std::any_cast<std::string>(a) << '\n';

    try {
        std::cout << std::any_cast<int>(a) << '\n';
    }
    catch (const std::bad_any_cast& e) {
        std::cout << e.what() << '\n';
    }

    return 0;
}


尝试手写any类

思考一下类型擦拭其实可以用 c++ 多态和模版来进行实现,使用同一个父类 Base 的指针,子类 Devide 使用模版记录下数据。

构造时:父类 Base 的指针指向子类的对象。
使用时:将父类 Base 的指针 cast 成相应的派生类指针 Devide<T>*
输出时:使用多态来调用 print 函数。

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

struct Any {
    Any() : ptr(nullptr) {}
    ~Any() {
        if(ptr) delete ptr;
    }
    template<typename T>
    Any(const T& t) : ptr(new Devide<T>(t)){}
    Any(const Any& rhs) { 
        cout << "正在使用拷贝构造" << endl;
        ptr = rhs.ptr -> clone();
    } // 拷贝构造
    Any(Any &&rhs) { // 移动构造
        cout << "正在使用移动构造" << endl;
        ptr = rhs.ptr;
        rhs.ptr = nullptr;
    }

    Any& operator= (const Any& rhs) { // 赋值构造
        cout << "正在使用赋值构造" << endl;
        if(ptr) delete ptr;
        ptr = rhs.ptr -> clone();
        return *this;
    }
    Any& operator= (Any&& rhs) {
        cout << "正在使用万能赋值构造" << endl;
        if(ptr) delete ptr;
        ptr = rhs.ptr;
        rhs.ptr = nullptr;
        return *this;
    }
    
    struct Base {
        virtual Base* clone() = 0;
        virtual ostream& print(ostream& out) = 0;
    };

    template<typename T>
    struct Devide : Base{
        T data;
        Devide(const T& t) : data(t){}
        virtual Base* clone() {return new Devide<T>(data);}
        virtual ostream& print(ostream& out) {
            out << data;
            return out;
        }
    };

    template<typename T>
    T& get_data() {
        return ((Devide<T>*)(ptr)) -> data;
    }

    Base* ptr;
};

ostream& operator << (ostream& out, const Any& rhs) {
    rhs.ptr -> print(out);
    return out;
}

int main() {
    Any a = 3;
    cout << a << endl;
    Any b = string{"111"};
    cout << b << endl;
    a = move(b);
    cout << a.get_data<string>() << endl;
    return 0;
}


/*
reference: https://zhuanlan.zhihu.com/p/597223487
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值