cpp*_*ner 2 c++ templates crtp c++17
我想将具有固定签名的待创建函数的名称注入到 CRTP(Curious recurring template pattern)基类中。
这是我现有的工作代码(coliru MCVE 链接):-
#include <iostream>
#include <string>
//--- library layer ---
template<class O,class Under> struct Crtp{
Under* oNo=nullptr;
auto getUnderlying(){
return oNo;
}
};
//--- user layer ex 1 ---
struct B{ // please don't edit this class
int k=0;
};
struct BO : Crtp<BO,B>{
auto getBOUn(){ return Crtp<BO,B>::getUnderlying();}
// some other functions
};
//--- user layer ex 2 ---
struct C{ // please don't edit this class
int kad=0;
};
struct CO : Crtp<CO,C>{
auto getCOUn(){ return Crtp<CO,C>::getUnderlying();}
// some other functions
};
int main() {
BO bo; B b; bo.Crtp<BO,B>::oNo=&b; //<-- please don't edit
std::cout<< bo.getBOUn()->k;
}
Run Code Online (Sandbox Code Playgroud)
我希望它会很简单:-
//--- user layer ex 1 ---
struct B{ // (same)
int k=0;
};
struct BO : Crtp<BO,B,getBOUn>{ //<--- so easy and clean
// some other functions
};
Run Code Online (Sandbox Code Playgroud)
可能吗,怎么可能?
我有 >100 个类对,例如B& BO; 他们有自己独特的自定义名称getBOUn()-like 函数。
我可以用宏修复它,但我不想要另一层混乱。
请不要用宏回答。
我经常创建这样的类:-
struct Walkable{
float stamina =0 ;
float speed =0;
};
struct WalkableO: Crtp<WalkableO,Walkable>{
auto getWalkUnderlying(){ return Crtp<BO,B>::getUnderlying();}
void runNow(){
if(getWalkUnderlying()->stamina >1 ){
getWalkUnderlying()->speed +=3;
getWalkUnderlying()->stamina --;
}
}
};
class Dog : public virtual WalkableO, public virtual HasHpO, public virtual EatenableO {};
Run Code Online (Sandbox Code Playgroud)
有时,我喜欢直接访问特定的底层代码:-
Dog* dogPtr; /** some ini ...*/ dogPtr->getWalkUnderlying()->stamina=10;
Run Code Online (Sandbox Code Playgroud)
有时,我想以更抽象的方式访问“其他一些功能”:-
dogOPtr->runNow(); //a custom function within WalkableO
Run Code Online (Sandbox Code Playgroud)
我使用虚拟继承,因为如果我重新设计,使例如每WalkableO到要 HasHpO过,我可以编辑如下面的代码。
我什至不需要更改Dog代码:-
struct WalkableO: Crtp<WalkableO,Walkable>, virtual HasHpO{/*something*/};
Run Code Online (Sandbox Code Playgroud)
Dog本身,可以是基类上BullDog,TigerDog等
不幸的是,您声明新函数的选择非常有限。
在这种情况下,您将引入一个新的identifier。之后预处理,一个识别符只能由一个引入的声明。在您的约束下,仅有的三种相关声明是simple-declaration s、function-definition s 和template-declaration s(在声明之上,在这种情况下必须是simple-declaration或function-definition因为它应该声明一个函数)。在模板声明中,,您声明的唯一名称是在底层中声明的名称simple-declaration或function-definition,所以我们基本上仅限于simple-declaration和function-definition。由简单声明或函数定义引入的名称在其declarator中指定,因此无法指定新标识符并自动声明它。
换句话说,在 C++ 中进行预处理后,无法“透明地”传递待声明的标识符。所以我不认为你想要做的事情是可能的。您必须使用宏,或自己声明函数。
| 归档时间: |
|
| 查看次数: |
202 次 |
| 最近记录: |