我想编写通过 ( 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_;
};
关于c++ - 通过CRTP简化相互扩展类的API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50197512/