Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
---

<!-- COVERAGE_START -->
![English Coverage](https://img.shields.io/badge/en_coverage-100%25-green.svg) 592/594 docs translated
![English Coverage](https://img.shields.io/badge/en_coverage-100%25-green.svg) 602/604 docs translated
<!-- COVERAGE_END -->

## 这是什么项目
Expand Down
30 changes: 30 additions & 0 deletions code/examples/vol4/vol1-basics-cpp11-14/comparable_mixin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Comparable<Derived>:CRTP mixin,只实现 < 和 ==,自动补齐 > <= >= !=
// 对应文章:documents/vol4-advanced/vol1-basics-cpp11-14/09-crtp.md
// 编译:g++ -Wall -Wextra -std=c++20 comparable_mixin.cpp -o comparable && ./comparable
#include <iostream>

template <typename Derived> struct Comparable {
friend bool operator>(const Derived& a, const Derived& b) { return b < a; }
friend bool operator<=(const Derived& a, const Derived& b) { return !(b < a); }
friend bool operator>=(const Derived& a, const Derived& b) { return !(a < b); }
friend bool operator!=(const Derived& a, const Derived& b) { return !(a == b); }
};

struct Point : Comparable<Point> {
int x, y;
Point(int x_, int y_) : x(x_), y(y_) {}
// 只实现 < 和 ==,其余四个由 Comparable<Point> 自动补齐
friend bool operator<(const Point& a, const Point& b) { return a.x < b.x; }
friend bool operator==(const Point& a, const Point& b) { return a.x == b.x; }
};

int main() {
Point p1{1, 2}, p2{3, 4};
std::cout << std::boolalpha;
std::cout << "p1 < p2: " << (p1 < p2) << "\n";
std::cout << "p1 > p2: " << (p1 > p2) << "\n";
std::cout << "p1 <= p2: " << (p1 <= p2) << "\n";
std::cout << "p1 >= p2: " << (p1 >= p2) << "\n";
std::cout << "p1 != p2: " << (p1 != p2) << "\n";
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// CRTP 静态多态:派生类把自己传给基类,编译期绑定,无 vtable 无运行时分派
// 对应文章:documents/vol4-advanced/vol1-basics-cpp11-14/09-crtp.md
// 编译运行:g++ -Wall -Wextra -std=c++20 crtp_static_polymorphism.cpp -o crtp && ./crtp
// 看零开销汇编:g++ -O2 -std=c++20 -DCRTP_BENCH -S crtp_static_polymorphism.cpp -o crtp.s
// use_crtp() 会被完全内联成 mov $0x2a,%eax; ret(对比虚函数版的 vtable 解引用)
#include <iostream>

template <typename Derived> struct Shape {
const char* name() { return static_cast<Derived*>(this)->name_impl(); }
double area() { return static_cast<Derived*>(this)->area_impl(); }
};

struct Circle : Shape<Circle> {
double r;
explicit Circle(double r_) : r(r_) {}
const char* name_impl() { return "Circle"; }
double area_impl() { return 3.14159 * r * r; }
};

struct Square : Shape<Square> {
double side;
explicit Square(double s) : side(s) {}
const char* name_impl() { return "Square"; }
double area_impl() { return side * side; }
};

#ifdef CRTP_BENCH
// 汇编基准:use_crtp 在 -O2 下被完全内联,直接返回常量 42,零函数调用
template <typename D> struct BenchBase {
int compute() { return static_cast<D*>(this)->compute_impl(); }
};
struct BenchConcrete : BenchBase<BenchConcrete> {
int compute_impl() { return 42; }
};
int use_crtp() {
BenchConcrete c;
return c.compute();
}
#endif

int main() {
Circle c{2.0};
Square s{3.0};
std::cout << c.name() << " area = " << c.area() << "\n"; // Circle 走 Circle::area_impl
std::cout << s.name() << " area = " << s.area() << "\n"; // Square 走 Square::area_impl
return 0;
}
46 changes: 46 additions & 0 deletions code/examples/vol4/vol1-basics-cpp11-14/fixed_vector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// fixed_vector<T, N>:编译期定长、连续存储、零动态分配的 vector
// 对应文章:documents/vol4-advanced/vol1-basics-cpp11-14/10-fixed-vector.md
// 编译:g++ -Wall -Wextra -std=c++20 fixed_vector.cpp -o fixed_vector && ./fixed_vector
#include <array>
#include <cstddef>
#include <iostream>
#include <stdexcept>

template <typename T, std::size_t N> class FixedVector {
std::array<T, N> data_{};
std::size_t size_ = 0;

public:
static constexpr std::size_t capacity_v = N;

constexpr void push_back(const T& value) {
if (size_ >= N)
throw std::out_of_range("FixedVector full");
data_[size_++] = value;
}
constexpr T& operator[](std::size_t i) { return data_[i]; }
constexpr const T& operator[](std::size_t i) const { return data_[i]; }
constexpr std::size_t size() const { return size_; }

// 裸指针当迭代器:元素连续存储,T* 天生满足随机访问迭代器要求
constexpr T* begin() { return data_.data(); }
constexpr T* end() { return data_.data() + size_; }
constexpr const T* begin() const { return data_.data(); }
constexpr const T* end() const { return data_.data() + size_; }
};

int main() {
FixedVector<int, 8> v;
for (int i = 1; i <= 5; ++i)
v.push_back(i * 10);

std::cout << "size = " << v.size() << " capacity = " << decltype(v)::capacity_v << "\n";
std::cout << "elements: ";
for (auto x : v)
std::cout << x << " ";
std::cout << "\n";
std::cout << "v[2] = " << v[2] << "\n";
std::cout << "sizeof(FixedVector<int,8>) = " << sizeof(FixedVector<int, 8>) << "\n";
std::cout << "sizeof(int*) = " << sizeof(int*) << " (动态 vector 至少含 3 个指针 + 堆分配)\n";
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 手写 type traits:主模板 + 偏特化,看穿 <type_traits> 的实现原理
// 对应文章:documents/vol4-advanced/vol1-basics-cpp11-14/04-specialization-partial.md
// 编译:g++ -Wall -Wextra -std=c++20 type_traits_from_scratch.cpp -o type_traits && ./type_traits
#include <iostream>

// is_pointer:主模板 false,指针偏特化 true
template <typename T> struct is_pointer {
static constexpr bool value = false;
};
template <typename T> struct is_pointer<T*> {
static constexpr bool value = true;
};

// is_const:主模板 false,const T 偏特化 true(注意 const T* 不算,得 T 本身是 const)
template <typename T> struct is_const {
static constexpr bool value = false;
};
template <typename T> struct is_const<const T> {
static constexpr bool value = true;
};

// is_reference:主模板 false,T& / T&& 偏特化 true
template <typename T> struct is_reference {
static constexpr bool value = false;
};
template <typename T> struct is_reference<T&> {
static constexpr bool value = true;
};
template <typename T> struct is_reference<T&&> {
static constexpr bool value = true;
};

// C++14 变量模板简写(和标准库 _v 后缀同一思路)
template <typename T> constexpr bool is_pointer_v = is_pointer<T>::value;

int main() {
std::cout << std::boolalpha;
std::cout << "is_pointer<int> = " << is_pointer<int>::value << "\n";
std::cout << "is_pointer<int*> = " << is_pointer<int*>::value << "\n";
std::cout << "is_pointer<int**> = " << is_pointer<int**>::value << "\n";
std::cout << "is_const<const int> = " << is_const<const int>::value << "\n";
std::cout << "is_const<int> = " << is_const<int>::value << "\n";
std::cout << "is_const<const int*> = " << is_const<const int*>::value
<< " (指针自身非 const,指向 const)\n";
std::cout << "is_const<int* const> = " << is_const<int* const>::value << " (指针自身 const)\n";
std::cout << "is_reference<int&> = " << is_reference<int&>::value << "\n";
std::cout << "is_reference<int&&> = " << is_reference<int&&>::value << "\n";
std::cout << "is_pointer_v<double> = " << is_pointer_v<double> << " (_v 简写)\n";
return 0;
}
Loading
Loading