1392: 锁爷已经忍你很久了
题目
题目描述
据说马上就要发布Python Interpreter
大作业了,小$L$同学发现完成大作业的途中碰到的antlr::Any
类非常有意思。尽管非常好奇这个类的底层实现,但是迫于能力有限,他希望实现一个自己的简易版的sjtu::Any
结构体。
sjtu::Any
结构体的原理
在结构体里面用一个void *
指针来指向不同类型的值的地址,借此实现对任意类型的值的存储。
用模板函数来接受任意类型的存储,也是用模板函数来制定需要转换到的类型,并且进行转换。
存放函数
通过函数模板获得类型,动态新建(new
)一个相同类型的备份,将指向它的指针强制类型转换为void *
存储。
类型转换函数
通过函数模板获得需要转换的类型,将void *
强制类型转换为对应类型指针获取内容。
为了检查类型之间是否匹配,可以使用c++
的type_info
类。
- 使用运算符
typeid()
可以获得一个type_info
的对象,typeid()
里面可以传入一个变量、表达式或者一个类型名。 type_info::name()
返回const char*
表示类型名。type_info::hash_code()
返回std::size_t
表示给这个类型名做哈希操作之后的结果。
例子
const char* name = typeid(int).name()
获得int
的类型名
std::size_t hashCode = typeid(int).hash_code()
获得int
类型的哈希值
namespace sjtu
接口介绍
sjtu::emplace<Type>(x, data)
:创建任意类型变量data
的备份并保存在sjtu::Any
结构体x
内- 注意传参的方式
- 返回
x
的引用。 sjtu::reset<Type>(x)
:将sjtu::Any
结构体x
中的指针释放,所有内容清空sjtu::has_value(x)
:返回bool
表示sjtu::Any
结构体x
是否存放内容sjtu::make_any<Type>(data)
:返回一个sjtu::Any
结构体,将任意类型变量data
存放进去sjtu::can_cast<Type>(x)
:返回bool
表示sjtu::Any
结构体x
里面是否存放类型为Type
的值sjtu::any_cast<Type>(x)
:返回Type
,将sjtu::Any
结构体x
的内容强制转换为Type
类型返回sjtu::destructor<Type>(x)
:析构sjtu::Any
结构体x
(比如释放内部的指针空间)
下面给出hpp
的框架,在每个TODO
下面填写对应的函数,直接提交namespace sjtu
即可。
```c++ namespace sjtu{ struct Any{ // TODO: add any definition you need };
// TODO: template function emplace()
// TODO: template function reset()
// TODO: function has_value()
// TODO: template function make_any()
// TODO: template function can_cast()
// TODO: template function any_cast()
// TODO: template function destructor()
} ```
数据范围
本题需要用valgrind
检查,请注意内存泄漏问题
保证所有sjtu::Any
对象会在使用结束后对它调用destructor()
函数
提示
关于强制类型转换
如果要将变量a
转换成Type
类型,可以使用(Type) a
。
如果不熟悉,可以参考下面的例子
c++
int a = 0;
char ch = (char) a;
第二行会把int
类的变量转换为char
类型变量。
如果不熟悉std::size_t
的话,cppreference
是这样解释的:
size_t
is the unsigned integer type of the result ofsizeof
, _Alignof
(since C11) andoffsetof
, depending on the data model.The bit width of
size_t
is not less than 16. (since C99)Notes
size_t
can store the maximum size of a theoretically possible object of any type (including array).
size_t
is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.
下面给出一份cpp
测试样例
```c++
include
using namespace std;
int main(){
sjtu::Any x;
cout << sjtu::has_value(x) << endl;
sjtu::emplace(x, true);
cout << sjtu::has_value(x) << endl;
sjtu::reset
把namespace sjtu
复制到using namespace std
和int main()
中间,运行的结果如下
text
0
1
1
0
123
Oops! 本题目还没有解答!
助教老师们编题的速度,已经超过了解题的速度!
OJ翻了一新,但本解答集还大多用的是2017-2019级,甚至更早的同学们贡献的答案。
如果你已经AC了,可以的话,请您参考添加页面,与大家一起分享你的题解!