Skip to content

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 of sizeof, _Alignof (since C11) and offsetof, 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(x); x = sjtu::make_any(123); cout << sjtu::can_cast(x) << endl; cout << sjtu::can_cast(x) << endl; cout << sjtu::any_cast(x) << endl; sjtu::destructor(x); return 0; } ```

namespace sjtu复制到using namespace stdint main()中间,运行的结果如下

text 0 1 1 0 123

Oops! 本题目还没有解答!

助教老师们编题的速度,已经超过了解题的速度!

OJ翻了一新,但本解答集还大多用的是2017-2019级,甚至更早的同学们贡献的答案。

如果你已经AC了,可以的话,请您参考添加页面,与大家一起分享你的题解!