From 390127962094a7490a75a5e6bb258d550ea6eaec Mon Sep 17 00:00:00 2001 From: abnerhexu Date: Sun, 16 Feb 2025 10:21:55 +0800 Subject: [PATCH] delete educoder created file --- .gitignore | 4 + programmming/01-class-construct/main.cc | 37 ++++++ programmming/02-class-destruct/main.cc | 31 +++++ programmming/03-class-clone/main.cc | 42 +++++++ programmming/04-class-move/main.cc | 67 +++++++++++ programmming/05-class-derive/main.cc | 52 ++++++++ programmming/06-class-virtual/main.cc | 82 +++++++++++++ .../07-class-virtual-destruct/main.cc | 62 ++++++++++ programmming/08-class-template/main.cc | 112 ++++++++++++++++++ programmming/checker.h | 19 +++ snippets/lec1/01-const-expr.cc | 11 ++ snippets/lec1/02-structured-binding.cc | 12 ++ snippets/lec1/03-type-inference-auto.cc | 10 ++ snippets/lec1/04-type-inference-decltype.cc | 11 ++ snippets/lec1/05-template-add.cc | 13 ++ snippets/lec1/06-template-with-auto.cc | 16 +++ snippets/lec1/07-template-args.cc | 14 +++ snippets/lec1/08-template-recursive-args.cc | 16 +++ snippets/lec1/09-template-unwrap-args.cc | 12 ++ snippets/lec1/10-vec-for-loop.cc | 16 +++ snippets/lec1/11-class-template.cc | 8 ++ snippets/lec1/12-non-class-template.cc | 19 +++ snippets/lec2/01-comparison.cc | 30 +++++ snippets/lec2/02-pythonic-add.cc | 12 ++ snippets/lec2/03-higher-order-functions.cc | 33 ++++++ snippets/lec2/py-01-lambda.py | 6 + snippets/lec2/py-02-higher-order-functions.py | 13 ++ snippets/lec3/01-std-shared-ptr.cc | 12 ++ snippets/lec3/py-gc.py | 15 +++ snippets/lec3/py-ref-count.py | 10 ++ src/.gitkeep | 0 31 files changed, 797 insertions(+) create mode 100644 .gitignore create mode 100644 programmming/01-class-construct/main.cc create mode 100644 programmming/02-class-destruct/main.cc create mode 100644 programmming/03-class-clone/main.cc create mode 100644 programmming/04-class-move/main.cc create mode 100644 programmming/05-class-derive/main.cc create mode 100644 programmming/06-class-virtual/main.cc create mode 100644 programmming/07-class-virtual-destruct/main.cc create mode 100644 programmming/08-class-template/main.cc create mode 100644 programmming/checker.h create mode 100644 snippets/lec1/01-const-expr.cc create mode 100644 snippets/lec1/02-structured-binding.cc create mode 100644 snippets/lec1/03-type-inference-auto.cc create mode 100644 snippets/lec1/04-type-inference-decltype.cc create mode 100644 snippets/lec1/05-template-add.cc create mode 100644 snippets/lec1/06-template-with-auto.cc create mode 100644 snippets/lec1/07-template-args.cc create mode 100644 snippets/lec1/08-template-recursive-args.cc create mode 100644 snippets/lec1/09-template-unwrap-args.cc create mode 100644 snippets/lec1/10-vec-for-loop.cc create mode 100644 snippets/lec1/11-class-template.cc create mode 100644 snippets/lec1/12-non-class-template.cc create mode 100644 snippets/lec2/01-comparison.cc create mode 100644 snippets/lec2/02-pythonic-add.cc create mode 100644 snippets/lec2/03-higher-order-functions.cc create mode 100644 snippets/lec2/py-01-lambda.py create mode 100644 snippets/lec2/py-02-higher-order-functions.py create mode 100644 snippets/lec3/01-std-shared-ptr.cc create mode 100644 snippets/lec3/py-gc.py create mode 100644 snippets/lec3/py-ref-count.py delete mode 100644 src/.gitkeep diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5975b16 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode +cc/build +*/__pycache__ +*.pyc \ No newline at end of file diff --git a/programmming/01-class-construct/main.cc b/programmming/01-class-construct/main.cc new file mode 100644 index 0000000..13b2108 --- /dev/null +++ b/programmming/01-class-construct/main.cc @@ -0,0 +1,37 @@ +#include "../checker.h" +#include +// C++ 中,`class` 和 `struct` 之间的**唯一区别**是 +// `class` 默认访问控制符是 `private`, +// `struct` 默认访问控制符是 `public`。 +// READ: 访问说明符 + +// 这个 class 中的字段被 private 修饰,只能在 class 内部访问。 +// 因此必须提供构造器来初始化字段。 +// READ: 构造器 + +// 缓存的Fibonacci数列计算: +// 可以考虑将之前计算好的结果保存到vector中,计算时先检查是否已经计算过,如果已经计算过, +// 直接返回结果,反之按照递推公式进行计算 + +class Fibonacci { + std::vector cache; + int cached; + +public: + // 实现构造器 初始化Fibonacci类的某些字段 + Fibonacci() {} + + // TODO: 实现正确的缓存优化斐波那契计算 + size_t get(int i) { + + } +}; + +int main() { + // 现在类型拥有无参构造器,声明时会直接调用。 + // 这个写法不再是未定义行为了。 + Fibonacci fib; + ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55"); + std::cout << "fibonacci(10) = " << fib.get(10) << std::endl; + return 0; +} diff --git a/programmming/02-class-destruct/main.cc b/programmming/02-class-destruct/main.cc new file mode 100644 index 0000000..af16739 --- /dev/null +++ b/programmming/02-class-destruct/main.cc @@ -0,0 +1,31 @@ +#include "../checker.h" + +// READ: 析构函数 +// READ: RAII + +// 构造任意缓存容量的斐波那契类型。 +// 可以在构造时传入缓存容量,因此需要动态分配缓存空间。 + +class DynFibonacci { + size_t *cache; + int cached; + +public: + // TODO: 实现动态设置容量的构造器 + DynFibonacci(int capacity) {} + + // TODO: 实现析构器,释放缓存空间 + ~DynFibonacci() {} + + // TODO: 实现正确的缓存优化斐波那契计算 + size_t get(int i) { + + } +}; + +int main(int argc, char **argv) { + DynFibonacci fib(12); + ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55"); + std::cout << "fibonacci(10) = " << fib.get(10) << std::endl; + return 0; +} \ No newline at end of file diff --git a/programmming/03-class-clone/main.cc b/programmming/03-class-clone/main.cc new file mode 100644 index 0000000..ea15b62 --- /dev/null +++ b/programmming/03-class-clone/main.cc @@ -0,0 +1,42 @@ +#include "../checker.h" +#include + +// READ: 复制构造函数 +// READ: 函数定义(显式弃置) + + +class Fibonacci { + std::vector cache; + int cached; + +public: + // TODO: 实现动态设置容量的构造器 + Fibonacci(int capacity) {} + + // TODO: 实现复制构造器 + Fibonacci(Fibonacci const &other) {} + + // TODO: 实现正确的缓存优化斐波那契计算 + size_t get(int i) { + + } + + // NOTICE: 不要修改这个方法 + // NOTICE: 名字相同参数也相同,但 const 修饰不同的方法是一对重载方法,可以同时存在 + // 本质上,方法是隐藏了 this 参数的函数 + // const 修饰作用在 this 上,因此它们实际上参数不同 + size_t get(int i) const { + if (i <= cached) { + return cache[i]; + } + ASSERT(false, "i out of range"); + } +}; + +int main(int argc, char **argv) { + Fibonacci fib(12); + ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55"); + Fibonacci const fib_ = fib; + ASSERT(fib_.get(10) == fib.get(10), "Object cloned"); + return 0; +} diff --git a/programmming/04-class-move/main.cc b/programmming/04-class-move/main.cc new file mode 100644 index 0000000..960e2cd --- /dev/null +++ b/programmming/04-class-move/main.cc @@ -0,0 +1,67 @@ +#include "../checker.h" +#include + +// READ: 左值右值(概念) +// READ: 左值右值(细节) +// READ: 关于移动语义 +// READ: 如果实现移动构造 + +// READ: 移动构造函数 +// READ: 移动赋值 +// READ: 运算符重载 + +class DynFibonacci { + size_t *cache; + int cached; + +public: + // TODO: 实现动态设置容量的构造器 + DynFibonacci(int capacity) {} + + // TODO: 实现移动构造器 + DynFibonacci(DynFibonacci && other) { + + }; + + // TODO: 实现移动赋值 + // NOTICE: ⚠ 注意移动到自身问题 ⚠ + DynFibonacci &operator=(DynFibonacci && other) noexcept { + // ASK AI: 这里的 noexcept 是什么含义? + } + + // TODO: 实现正确的缓存优化斐波那契计算 + // 我们重载了下标运算符,请给出正确的实现 + size_t operator[](int i) { + + } + + // NOTICE: 不要修改这个方法 + // THINK: 这个方法和上面的方法有什么不同? + size_t operator[](int i) const { + ASSERT(i <= cached, "i out of range"); + return cache[i]; + } + + // NOTICE: 不要修改这个方法 + bool is_alive() const { + return cache; + } +}; + +int main(int argc, char **argv) { + DynFibonacci fib(12); + ASSERT(fib[10] == 55, "fibonacci(10) should be 55"); + + DynFibonacci const fib_ = std::move(fib); + ASSERT(!fib.is_alive(), "Object moved"); + ASSERT(fib_[10] == 55, "fibonacci(10) should be 55"); + + DynFibonacci fib0(6); + DynFibonacci fib1(12); + + fib0 = std::move(fib1); + fib0 = std::move(fib0); + ASSERT(fib0[10] == 55, "fibonacci(10) should be 55"); + + return 0; +} diff --git a/programmming/05-class-derive/main.cc b/programmming/05-class-derive/main.cc new file mode 100644 index 0000000..b200539 --- /dev/null +++ b/programmming/05-class-derive/main.cc @@ -0,0 +1,52 @@ +#include "../checker.h" + +// READ: 派生类 + +class Instruction { +public: + uint32_t raw; +public: + Instruction(uint32_t raw) : raw(raw) {} +}; + +class RTypeInstruction: public Instruction { +public: + RTypeInstruction(uint32_t raw) : Instruction(raw) {} + void get_rs1() { + std::cout << ((this->raw >> 15) & 0b11111) << std::endl; + } + void get_rs2() { + std::cout << ((this->raw >> 20) & 0b11111) << std::endl; + } + void get_rd() { + std::cout << ((this->raw >> 7) & 0b11111) << std::endl; + } + std::string get_op() { + return "Not implementaed due to unknown instruction type"; + } +}; + +class AddInst: public RTypeInstruction { +public: + AddInst(uint32_t raw) : RTypeInstruction(raw) {} + std::string get_op() { + return "add op"; + } +}; + +int main() { + auto inst = AddInst(0x00728b33); + inst.get_rs1(); + inst.get_rs2(); + inst.get_rd(); + inst.get_op(); + auto rinst1 = dynamic_cast(&inst); + if (rinst1) { + // TODO: 填入正确答案 + ASSERT(rinst1->get_op() == "", "get_op() should return " + rinst1->get_op()); + } + RTypeInstruction rinst2 = inst; + // TODO: 填入正确答案 + ASSERT(rinst2.get_op() == "", "get_op() should return " + rinst2.get_op()); + return 0; +} \ No newline at end of file diff --git a/programmming/06-class-virtual/main.cc b/programmming/06-class-virtual/main.cc new file mode 100644 index 0000000..8d37988 --- /dev/null +++ b/programmming/06-class-virtual/main.cc @@ -0,0 +1,82 @@ +#include "../checker.h" + +// READ: 虚函数 + +struct A { + virtual char virtual_name() const { + return 'A'; + } + char direct_name() const { + return 'A'; + } +}; +struct B : public A { + // READ: override + char virtual_name() const override { + return 'B'; + } + char direct_name() const { + return 'B'; + } +}; +struct C : public B { + // READ: final + char virtual_name() const final { + return 'C'; + } + char direct_name() const { + return 'C'; + } +}; +struct D : public C { + char direct_name() const { + return 'D'; + } +}; + +int main(int argc, char **argv) { + constexpr auto MSG = "Replace '?' with its correct name."; + + A a; + B b; + C c; + D d; + + ASSERT(a.virtual_name() == '?', MSG); + ASSERT(b.virtual_name() == '?', MSG); + ASSERT(c.virtual_name() == '?', MSG); + ASSERT(d.virtual_name() == '?', MSG); + ASSERT(a.direct_name() == '?', MSG); + ASSERT(b.direct_name() == '?', MSG); + ASSERT(c.direct_name() == '?', MSG); + ASSERT(d.direct_name() == '?', MSG); + + A &rab = b; + B &rbc = c; + C &rcd = d; + + ASSERT(rab.virtual_name() == '?', MSG); + ASSERT(rbc.virtual_name() == '?', MSG); + ASSERT(rcd.virtual_name() == '?', MSG); + ASSERT(rab.direct_name() == '?', MSG); + ASSERT(rbc.direct_name() == '?', MSG); + ASSERT(rcd.direct_name() == '?', MSG); + + A &rac = c; + B &rbd = d; + + ASSERT(rac.virtual_name() == '?', MSG); + ASSERT(rbd.virtual_name() == '?', MSG); + ASSERT(rac.direct_name() == '?', MSG); + ASSERT(rbd.direct_name() == '?', MSG); + + A &rad = d; + + ASSERT(rad.virtual_name() == '?', MSG); + ASSERT(rad.direct_name() == '?', MSG); + + return 0; +} + +// READ: 扩展阅读-纯虚、抽象 +// READ: 扩展阅读-虚继承 \ No newline at end of file diff --git a/programmming/07-class-virtual-destruct/main.cc b/programmming/07-class-virtual-destruct/main.cc new file mode 100644 index 0000000..bd1124f --- /dev/null +++ b/programmming/07-class-virtual-destruct/main.cc @@ -0,0 +1,62 @@ +#include "../checker.h" + +struct A { + // TODO: 正确初始化静态字段 + static int num_a = 0; + + A() { + ++num_a; + } + ~A() { + --num_a; + } + + virtual char name() const { + return 'A'; + } +}; +struct B final : public A { + // TODO: 正确初始化静态字段 + static int num_b = 0; + + B() { + ++num_b; + } + ~B() { + --num_b; + } + + char name() const final { + return 'B'; + } +}; + +int main(int argc, char **argv) { + auto a = new A; + auto b = new B; + ASSERT(A::num_a == ?, "Fill in the correct value for A::num_a"); + ASSERT(B::num_b == ?, "Fill in the correct value for B::num_b"); + ASSERT(a->name() == '?', "Fill in the correct value for a->name()"); + ASSERT(b->name() == '?', "Fill in the correct value for b->name()"); + + delete a; + delete b; + ASSERT(A::num_a == 0, "Every A was destroyed"); + ASSERT(B::num_b == 0, "Every B was destroyed"); + + A *ab = new B;// 派生类指针可以随意转换为基类指针 + ASSERT(A::num_a == ?, "Fill in the correct value for A::num_a"); + ASSERT(B::num_b == ?, "Fill in the correct value for B::num_b"); + ASSERT(ab->name() == '?', "Fill in the correct value for ab->name()"); + + // TODO: 基类指针无法随意转换为派生类指针,补全正确的转换语句 + B &bb = *ab; + ASSERT(bb.name() == '?', "Fill in the correct value for bb->name()"); + + // TODO: ---- 以下代码不要修改,通过改正类定义解决编译问题 ---- + delete ab;// 通过指针可以删除指向的对象,即使是多态对象 + ASSERT(A::num_a == 0, "Every A was destroyed"); + ASSERT(B::num_b == 0, "Every B was destroyed"); + + return 0; +} \ No newline at end of file diff --git a/programmming/08-class-template/main.cc b/programmming/08-class-template/main.cc new file mode 100644 index 0000000..7fde26f --- /dev/null +++ b/programmming/08-class-template/main.cc @@ -0,0 +1,112 @@ +#include "../checker.h" +#include +// READ: 类模板 + +template +struct Tensor4D { + unsigned int shape[4]; + T *data; + + Tensor4D(unsigned int const shape_[4], T const *data_) { + unsigned int size = 1; + // TODO: 填入正确的 shape 并计算 size + + data = new T[size]; + std::memcpy(data, data_, size * sizeof(T)); + } + ~Tensor4D() { + delete[] data; + } + + // 为了保持简单,禁止复制和移动 + Tensor4D(Tensor4D const &) = delete; + Tensor4D(Tensor4D &&) noexcept = delete; + + // 这个加法需要支持“单向广播”。 + // 具体来说,`others` 可以具有与 `this` 不同的形状,形状不同的维度长度必须为 1。 + // `others` 长度为 1 但 `this` 长度不为 1 的维度将发生广播计算。 + // 例如,`this` 形状为 `[1, 2, 3, 4]`,`others` 形状为 `[1, 2, 1, 4]`, + // 则 `this` 与 `others` 相加时,3 个形状为 `[1, 2, 1, 4]` 的子张量各自与 `others` 对应项相加。 + Tensor4D &operator+=(Tensor4D const &others) { + // TODO: 实现单向广播的加法 + // check whether a dimension needs broadcast + + return *this; + } +}; + +// ---- 不要修改以下代码 ---- +int main(int argc, char **argv) { + { + unsigned int shape[]{1, 2, 3, 4}; + // clang-format off + int data[]{ + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + + 13, 14, 15, 16, + 17, 18, 19, 20, + 21, 22, 23, 24}; + // clang-format on + auto t0 = Tensor4D(shape, data); + auto t1 = Tensor4D(shape, data); + t0 += t1; + for (auto i = 0u; i < sizeof(data) / sizeof(*data); ++i) { + ASSERT(t0.data[i] == data[i] * 2, "Tensor doubled by plus its self."); + } + } + { + unsigned int s0[]{1, 2, 3, 4}; + // clang-format off + float d0[]{ + 1, 1, 1, 1, + 2, 2, 2, 2, + 3, 3, 3, 3, + + 4, 4, 4, 4, + 5, 5, 5, 5, + 6, 6, 6, 6}; + // clang-format on + unsigned int s1[]{1, 2, 3, 1}; + // clang-format off + float d1[]{ + 6, + 5, + 4, + + 3, + 2, + 1}; + // clang-format on + + auto t0 = Tensor4D(s0, d0); + auto t1 = Tensor4D(s1, d1); + t0 += t1; + for (auto i = 0u; i < sizeof(d0) / sizeof(*d0); ++i) { + ASSERT(t0.data[i] == 7.f, "Every element of t0 should be 7 after adding t1 to it."); + } + } + { + unsigned int s0[]{1, 2, 3, 4}; + // clang-format off + double d0[]{ + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + + 13, 14, 15, 16, + 17, 18, 19, 20, + 21, 22, 23, 24}; + // clang-format on + unsigned int s1[]{1, 1, 1, 1}; + double d1[]{1}; + + auto t0 = Tensor4D(s0, d0); + auto t1 = Tensor4D(s1, d1); + t0 += t1; + for (auto i = 0u; i < sizeof(d0) / sizeof(*d0); ++i) { + ASSERT(t0.data[i] == d0[i] + 1, "Every element of t0 should be incremented by 1 after adding t1 to it."); + } + } +} diff --git a/programmming/checker.h b/programmming/checker.h new file mode 100644 index 0000000..29c7225 --- /dev/null +++ b/programmming/checker.h @@ -0,0 +1,19 @@ +#ifndef __EXERCISE_H__ +#define __EXERCISE_H__ + +#include + +#define ASSERT(COND, MSG) \ + if (!(COND)) { \ + std::cerr << "\x1b[31mAssertion failed at line #" << __LINE__ << ": \x1b[0m" << std::endl \ + << std::endl \ + << #COND << std::endl \ + << std::endl \ + << "\x1b[34mMessage:\x1b[0m" << std::endl \ + << std::endl \ + << MSG << std::endl \ + << std::endl; \ + exit(1); \ + } + +#endif// __EXERCISE_H__ \ No newline at end of file diff --git a/snippets/lec1/01-const-expr.cc b/snippets/lec1/01-const-expr.cc new file mode 100644 index 0000000..1809955 --- /dev/null +++ b/snippets/lec1/01-const-expr.cc @@ -0,0 +1,11 @@ +#include + +constexpr int fibonacci(const int n) { + return n == 1 || n == 2 ? 1 : fibonacci(n-1)+fibonacci(n-2); +} + +int main(){ + int fib_5 = fibonacci(5); + std::cout << "fib 5: " << fib_5 << std::endl; + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/02-structured-binding.cc b/snippets/lec1/02-structured-binding.cc new file mode 100644 index 0000000..168bff2 --- /dev/null +++ b/snippets/lec1/02-structured-binding.cc @@ -0,0 +1,12 @@ +#include +#include + +std::tuple get_data() { + return std::make_tuple(1, 2.71828, "hello"); +} + +int main() { + auto [a, b, c] = get_data(); + std::cout << a << " " << b << " " << c << std::endl; + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/03-type-inference-auto.cc b/snippets/lec1/03-type-inference-auto.cc new file mode 100644 index 0000000..af015be --- /dev/null +++ b/snippets/lec1/03-type-inference-auto.cc @@ -0,0 +1,10 @@ +#include +#include + +int main() { + std::vector vec; + std::vector::const_iterator a = vec.cbegin(); + // using type inference + auto b = vec.cbegin(); + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/04-type-inference-decltype.cc b/snippets/lec1/04-type-inference-decltype.cc new file mode 100644 index 0000000..892e6af --- /dev/null +++ b/snippets/lec1/04-type-inference-decltype.cc @@ -0,0 +1,11 @@ +#include + +int main() { + auto x = 1; + auto y = 2.0; + decltype(x+y) z; + if (std::is_same::value) { + std::cout << "x+y is double" << std::endl; + } + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/05-template-add.cc b/snippets/lec1/05-template-add.cc new file mode 100644 index 0000000..ef3d1c3 --- /dev/null +++ b/snippets/lec1/05-template-add.cc @@ -0,0 +1,13 @@ +#include + +template +T add(T a, T b) { + return a + b; +} + +int main() { + double a = 1.0; + double b = 2.0; + std::cout << add(a, b) << std::endl; + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/06-template-with-auto.cc b/snippets/lec1/06-template-with-auto.cc new file mode 100644 index 0000000..a7694c9 --- /dev/null +++ b/snippets/lec1/06-template-with-auto.cc @@ -0,0 +1,16 @@ +#include + +template +auto add(T x, U y){ + return x + y; +} + +int main() { + int a = 1; + double b = 2.71828; + std::cout << add(a, b) << std::endl; + if (std::is_same::value) { + std::cout << "result type of add(a, b) is double!" << std::endl; + } + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/07-template-args.cc b/snippets/lec1/07-template-args.cc new file mode 100644 index 0000000..a524e1b --- /dev/null +++ b/snippets/lec1/07-template-args.cc @@ -0,0 +1,14 @@ +#include + +template +void magic(Ts... args) { + std::cout << sizeof...(args) << std::endl; +} + +int main() { + magic(); + magic(1); + magic(1, 2); + magic(1, "hello", "world"); + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/08-template-recursive-args.cc b/snippets/lec1/08-template-recursive-args.cc new file mode 100644 index 0000000..1ab4d3a --- /dev/null +++ b/snippets/lec1/08-template-recursive-args.cc @@ -0,0 +1,16 @@ +#include +template +void my_printf(T value) { + std::cout << value << std::endl; +} + +template +void my_printf(T value, Ts... args) { + std::cout << value << std::endl; + my_printf(args...); +} + +int main() { + my_printf(1, 2, "San Francisco", 1.1); + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/09-template-unwrap-args.cc b/snippets/lec1/09-template-unwrap-args.cc new file mode 100644 index 0000000..8fa37d2 --- /dev/null +++ b/snippets/lec1/09-template-unwrap-args.cc @@ -0,0 +1,12 @@ +#include + +template +void my_printf(T t0, Ts... t) { + std::cout << t0 << std::endl; + if constexpr (sizeof...(t) > 0) my_printf(t...); +} + +int main() { + my_printf(1, 2, "San Francisco", 1.1); + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/10-vec-for-loop.cc b/snippets/lec1/10-vec-for-loop.cc new file mode 100644 index 0000000..c348eae --- /dev/null +++ b/snippets/lec1/10-vec-for-loop.cc @@ -0,0 +1,16 @@ +#include +#include + +int main() { + std::vector v = {1, 2, 3, 4, 5}; + for (auto it: v) { + std::cout << it << std::endl; + } + for (auto &it: v) { + it = it * 2; + } + for (auto it: v) { + std::cout << it << std::endl; + } + return 0; +} \ No newline at end of file diff --git a/snippets/lec1/11-class-template.cc b/snippets/lec1/11-class-template.cc new file mode 100644 index 0000000..60930b8 --- /dev/null +++ b/snippets/lec1/11-class-template.cc @@ -0,0 +1,8 @@ +template +struct point { + T x; + T y; +}; + +point p1{1.0, 2.0}; +point p2{1, 2}; \ No newline at end of file diff --git a/snippets/lec1/12-non-class-template.cc b/snippets/lec1/12-non-class-template.cc new file mode 100644 index 0000000..cfb7d0e --- /dev/null +++ b/snippets/lec1/12-non-class-template.cc @@ -0,0 +1,19 @@ +#include + +// define a template for calculating factorial +template +struct Factorial { + static const int value = N * Factorial::value; +}; + +// specialized template to end the factorial recursive +template<> +struct Factorial<0> { + static const int value = 1; +}; + +int main() { + std::cout << "Factorial of 5 is: " << Factorial<5>::value << std::endl; + std::cout << "Factorial of 10 is: " << Factorial<10>::value << std::endl; + return 0; +} diff --git a/snippets/lec2/01-comparison.cc b/snippets/lec2/01-comparison.cc new file mode 100644 index 0000000..8d8f4fc --- /dev/null +++ b/snippets/lec2/01-comparison.cc @@ -0,0 +1,30 @@ +#include +#include +#include + +struct CppRecord { + size_t id; + double value; +}; + +int main() { + std::vector records = { + {1, 3.5}, + {2, 2.0}, + {3, 3.5}, + {4, 1.0}, + {5, 2.0}}; + + std::sort(records.begin(), records.end(), [](const CppRecord& a, const CppRecord& b) { + if (a.value != b.value) { + return a.value < b.value; + } else { + return a.id < b.id; + } + }); + + for (const auto& record : records) { + std::cout << record.id << " " << record.value << std::endl; + } + return 0; +} \ No newline at end of file diff --git a/snippets/lec2/02-pythonic-add.cc b/snippets/lec2/02-pythonic-add.cc new file mode 100644 index 0000000..a9f354d --- /dev/null +++ b/snippets/lec2/02-pythonic-add.cc @@ -0,0 +1,12 @@ +#include + +int main() { + auto add = [](auto x, auto y) { + return x+y; + }; + + auto r1 = add(1, 2); + auto r2 = add(1.1, 2.2); + std::cout << r1 << " " << r2 << std::endl; + return 0; +} \ No newline at end of file diff --git a/snippets/lec2/03-higher-order-functions.cc b/snippets/lec2/03-higher-order-functions.cc new file mode 100644 index 0000000..1d4a884 --- /dev/null +++ b/snippets/lec2/03-higher-order-functions.cc @@ -0,0 +1,33 @@ +#include +#include +#include + +// define a higher order function, composing all functions together +template +std::function compose(std::vector> functions) { + return [functions](T x) { + T result = x; + // apply all these function from the right to the left + for (auto it = functions.rbegin(); it != functions.rend(); ++it) { + result = (*it)(result); + } + return result; + }; +} + +int main() { + // define a couple of simple functions + auto add_one = [](int x) { return x + 1; }; + auto square = [](int x) { return x * x; }; + auto double_value = [](int x) { return x * 2; }; + + // compose the functions + std::vector> functions = {double_value, square, add_one}; + auto pipeline = compose(functions); + + // test the composed functions + int result = pipeline(3); + std::cout << result << std::endl; // output: 32 + + return 0; +} \ No newline at end of file diff --git a/snippets/lec2/py-01-lambda.py b/snippets/lec2/py-01-lambda.py new file mode 100644 index 0000000..46deffb --- /dev/null +++ b/snippets/lec2/py-01-lambda.py @@ -0,0 +1,6 @@ +a = [42, 23, -17, 11, -8, 15, -38, 23, 18, -1] + +# sort by absolute value +a.sort(key=lambda x: abs(x)) + +print(a) \ No newline at end of file diff --git a/snippets/lec2/py-02-higher-order-functions.py b/snippets/lec2/py-02-higher-order-functions.py new file mode 100644 index 0000000..3784ccc --- /dev/null +++ b/snippets/lec2/py-02-higher-order-functions.py @@ -0,0 +1,13 @@ +# define a higher order function +# note: this function receives a function as an argument +def apply_twice(func, x): + # note: this function returns a function + return func(func(x)) + +# define a simple function +def square(x): + return x * x + +# use this higher order function +result = apply_twice(square, 2) +print(result) # output: 16 \ No newline at end of file diff --git a/snippets/lec3/01-std-shared-ptr.cc b/snippets/lec3/01-std-shared-ptr.cc new file mode 100644 index 0000000..9bca134 --- /dev/null +++ b/snippets/lec3/01-std-shared-ptr.cc @@ -0,0 +1,12 @@ +#include +#include +void foo(std::shared_ptr p) { + (*p)++; +} + +void create() { + std::shared_ptr p = std::make_shared(42); + foo(p); + // p is still valid + std::cout << *p << std::endl; +} // when leaving this scope, p will be destroyed (deleted) \ No newline at end of file diff --git a/snippets/lec3/py-gc.py b/snippets/lec3/py-gc.py new file mode 100644 index 0000000..388cef4 --- /dev/null +++ b/snippets/lec3/py-gc.py @@ -0,0 +1,15 @@ +import gc + +class FooClass: + def __init__(self): + self.value = 1 + def __del__(self): + print(f"FooClass {id(self)} destroyed!") + +foo1 = FooClass() +foo2 = foo1 +del foo1 +print("Called del foo1") +gc.collect() +foo2.value += 1 +print("Called foo2.value += 1") \ No newline at end of file diff --git a/snippets/lec3/py-ref-count.py b/snippets/lec3/py-ref-count.py new file mode 100644 index 0000000..c612639 --- /dev/null +++ b/snippets/lec3/py-ref-count.py @@ -0,0 +1,10 @@ +import sys +a = [1, 2, 3] +print(f"a's reference count: {sys.getrefcount(a)}") +b = a +print(f"a's reference count: {sys.getrefcount(a)}") +print(f"b's reference count: {sys.getrefcount(b)}") +del b +print(f"a's reference count: {sys.getrefcount(a)}") +del a +print(f"a's reference count: {sys.getrefcount(a)}") \ No newline at end of file diff --git a/src/.gitkeep b/src/.gitkeep deleted file mode 100644 index e69de29..0000000