C++CRTP奇异递归模板
奇异递归模板模式(CRTP)是派生类将自己作为模板参数传递给基类的技术。CRTP实现静态多态,避免了虚函数的运行时开销。
CRTP的基本形式:基类模板接受派生类作为参数。
#include
#include
template
class Base {
public:
void interface() {
static_cast(this)->implementation();
}
static void static_interface() {
Derived::static_implementation();
}
Derived& derived() {
return static_cast(*this);
}
const Derived& derived() const {
return static_cast(*this);
}
};
class DerivedA : public Base {
public:
void implementation() {
std::cout << "DerivedA implementation\n";
}
static void static_implementation() {
std::cout << "DerivedA static\n";
}
};
class DerivedB : public Base {
public:
void implementation() {
std::cout << "DerivedB implementation\n";
}
static void static_implementation() {
std::cout << "DerivedB static\n";
}
};
void crtp_basic() {
DerivedA a;
DerivedB b;
a.interface();
b.interface();
Base::static_interface();
Base::static_interface();
}
CRTP实现对象计数。
template
class ObjectCounter {
static inline int count_ = 0;
static inline int alive_ = 0;
protected:
ObjectCounter() {
++count_;
++alive_;
}
~ObjectCounter() {
--alive_;
}
public:
static int total_created() { return count_; }
static int currently_alive() { return alive_; }
};
class Widget : public ObjectCounter {
int id_;
public:
Widget(int id) : id_(id) {}
int id() const { return id_; }
};
void object_counter_demo() {
std::cout << "Initial: " << Widget::currently_alive() << "\n";
{
Widget w1(1);
Widget w2(2);
std::cout << "Two created: " << Widget::currently_alive() << "\n";
std::cout << "Total created: " << Widget::total_created() << "\n";
}
std::cout << "After scope: " << Widget::currently_alive() << "\n";
}
CRTP实现比较运算符。
template
class EqualComparable {
public:
friend bool operator==(const Derived& a, const Derived& b) {
return a.equal_to(b);
}
friend bool operator!=(const Derived& a, const Derived& b) {
return !a.equal_to(b);
}
};
template
class Comparable : public EqualComparable {
public:
friend bool operator<(const Derived& a, const Derived& b) {
return a.less_than(b);
}
friend bool operator>(const Derived& a, const Derived& b) {
return b.less_than(a);
}
friend bool operator<=(const Derived& a, const Derived& b) {
return !b.less_than(a);
}
friend bool operator>=(const Derived& a, const Derived& b) {
return !a.less_than(b);
}
};
class Point : public Comparable {
int x_, y_;
public:
Point(int x, int y) : x_(x), y_(y) {}
bool equal_to(const Point& other) const {
return x_ == other.x_ && y_ == other.y_;
}
bool less_than(const Point& other) const {
if (x_ != other.x_) return x_ < other.x_;
return y_ < other.y_;
}
friend std::ostream& operator<<(std::ostream& os, const Point& p) {
os << "(" << p.x_ << "," << p.y_ << ")";
return os;
}
};
void comparable_demo() {
Point p1(1, 2), p2(1, 2), p3(3, 4);
std::cout << p1 << " == " << p2 << ": " << (p1 == p2) << "\n";
std::cout << p1 << " != " << p3 << ": " << (p1 != p3) << "\n";
std::cout << p1 << " < " << p3 << ": " << (p1 < p3) << "\n";
std::cout << p3 << " > " << p1 << ": " << (p3 > p1) << "\n";
std::cout << p3 << " >= " << p1 << ": " << (p3 >= p1) << "\n";
}
CRTP实现单例。
template
class Singleton {
public:
static T& instance() {
static T instance_;
return instance_;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
protected:
Singleton() = default;
~Singleton() = default;
};
class Logger : public Singleton {
friend class Singleton;
int log_count_ = 0;
Logger() = default;
public:
void log(const std::string& msg) {
std::cout << "[LOG " << ++log_count_ << "] " << msg << "\n";
}
};
void singleton_crtp() {
auto& logger = Logger::instance();
logger.log("First message");
logger.log("Second message");
auto& logger2 = Logger::instance();
std::cout << "Same instance: " << (&logger == &logger2) << "\n";
}
CRTP实现克隆。
template
class Cloneable {
public:
std::unique_ptr clone() const {
return std::unique_ptr(
static_cast(this->clone_impl())
);
}
private:
virtual Cloneable* clone_impl() const = 0;
};
class ConcreteCloneable : public Cloneable {
int value_;
public:
explicit ConcreteCloneable(int v) : value_(v) {}
ConcreteCloneable* clone_impl() const override {
return new ConcreteCloneable(value_);
}
int value() const { return value_; }
};
void clone_demo() {
ConcreteCloneable original(42);
auto copy = original.clone();
std::cout << "Cloned value: " << copy->value() << "\n";
}
CRTP在C++中广泛应用,结合了模板的编译期效率和面向对象的表达力。
C++CRTP奇异递归模板
张小明
前端开发工程师
计算机毕业设计之食堂无忧:智能预约系统在校园餐饮管理
随着高校规模的不断扩大和学生需求的日益多样化,校园餐饮管理面临着前所未有的挑战。传统的人工管理方式已难以满足高效、精准的服务需求,因此开发一套基于现代信息技术的校园餐饮智能预约系统显得尤为重要。本研究旨在通过Spring Boot框架结合Java语言构…
做科技海报总没创作思路?5 个宝藏灵感站一键拓宽视野
每次接到科技类设计需求,很容易陷入视觉同质化困境:展会主视觉版式老旧、数码产品海报光效千篇一律、AI 科创宣传画面元素重复,不管是企业美工、活动策划还是自由设计师,翻遍图库也很难找到有差异化的创意参考。想要跳出固化模板&…
元宇宙经济动态定价:Solidity+Chainlink实战
发散创新:基于 Solidity Chainlink 的元宇宙经济动态定价合约设计与实战 在元宇宙经济系统中,静态定价模型已全面失效。虚拟土地、数字藏品(NFT)、跨域服务通证(如 DAO 治理权、算力租赁凭证)的价值高度依…
[特殊字符] 宝藏开源音乐播放器 Alger Music Player
🎵 宝藏开源音乐播放器 Alger Music Player 深度安利!颜值在线功能强大,音乐控必装!🔥✨ 大家好!我是你们的老朋友~今天又来给大家挖宝了!💎 最近后台有不少小伙伴私信我…
【扣子Coze教程】一分不花!用智能体3分钟搞定“早安电台“
大家好,我是爱玩AI的不正经绣才。经常刷抖音的同学,应该对"早安电台"这类情感视频不陌生,简短的文案,搭配街景,内容温馨治愈。今天我们用扣子Coze智能体3分钟搞定"早安电台",步骤非常简…
[智能体-448]:Coze三种 Agent 模式 ↔ 企业组织成熟度完整类比:完美对应企业从初创到标准化、再到团队化(集团化)
三种 Agent 底层调度逻辑,完美对应企业从初创到标准化、再到集团化的三阶段组织演进,管控权、分工、流程约束、资源归属完全对齐。一、第一阶段:单 Agent(自主规划模式) 初创个体户 / 一人公司组织形态类比创始人单人全…