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
*/