c++ - 通过 CRTP 简化类相互扩展的 API
问题描述
我想编写通过( CRTP)扩展多个类的类。
我只能Extension<Base<Extension>> my_object;
去上班了。
我想要的api是:Extension<Base> my_object;
如何使这个 api 工作?
谢谢。
测试(代码也在godbolt.org):
#include <iostream>
template <template<typename...> class Extension>
class Base1 : public Extension<Base1<Extension>> {
public:
static void beep() { std::cout << "Base1 "; }
};
template <class Plugin>
class Extension1 {
public:
Extension1() : plugin_(static_cast<Plugin*>(this)) {}
void beep() {
plugin_->beep();
std::cout << "Extension1\n";
}
private:
Plugin* plugin_;
};
template <template<typename...> class Plugin>
class Extension2 {
public:
Extension2() : plugin_(static_cast<Plugin<Extension2>*>(this)) {}
void beep() {
plugin_->beep();
std::cout << "Extension2\n";
}
private:
Plugin<Extension2>* plugin_;
};
int main() {
// This works.
Extension1<Base1<Extension1>>b;
b.beep();
// This doesn't work.
Extension2<Base1> c;
c.beep();
return 0;
}
解决方案
一个问题是模板参数与具有Extension2
的签名不匹配Base1
。另一个是Extension2
与预期的参数类型不匹配Base1
。
如果您将 的定义更改为Extension2
正确地接受Base1
,它本身仍然不是要传递给的候选人Base1
。您可以使用与Base1
预期匹配的内部模板类来解决此问题。这个内部类看起来很像Extension1
.
template <template<template<typename...> class> class Plugin>
class Extension2 {
template <class P>
struct Inner {
Inner () : plugin_(static_cast<P *>(this)) {}
void beep() { plugin_->beep(); }
private:
P* plugin_;
};
public:
Extension2() {}
void beep() {
plugin_.beep();
std::cout << "Extension2\n";
}
private:
Inner<Plugin<Inner>> plugin_;
};
推荐阅读
- python - Cython:如何加速递归函数?
- salesforce - 如何在 Salesforce 社区中创建包含用户列表的页面?
- json - Flutter 异常错误处理 Google Apps 脚本生成的 json
- java - 如何在 Ubuntu 20.04 上安装 JavaFX
- javascript - 使用 FirebaseAuthentication 创建用户后,Firebase 不会将用户数据保存到 Firestore - Angular 9
- java - PeriodicRequest 不起作用。我尝试每 15 分钟发送一次通知,但它不起作用
- reactjs - 在“节点”上执行“removeChild”失败:要删除的节点不是该节点的子节点。在反应
- angular - 我正在尝试在自定义组件中使用超级选项卡,但内容不可见
- google-sheets - 如何获取行列表元素比较两行谷歌表格
- python - 计算 A * relu(A * X * W0) * W1 wrt A 的梯度