将带有固定签名的自定义函数名注入 CRTP

inject a custom function-name with a fixed signature into CRTP

我想将一个 name 注入到 CRTP(Curiously recurring template pattern)base class 中,用于具有相当固定签名的待创建函数。

这是我现有的工作代码 (coliru MCVE link) :-

#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; 
}

我希望它会像 :-

一样简单
//--- user layer ex 1 ---
struct B{  // (same)
    int k=0;
};
struct BO : Crtp<BO,B,getBOUn>{  //<--- so easy and clean
    // some other functions
};

可以吗,怎么办?

我有超过 100 class 对,例如 BBO;他们有自己独特的自定义名称,用于类似 getBOUn() 的功能。

我可以用宏修复它,但我不想要另一层混乱。
请不要使用宏回答。

实际用例

我经常像这样创建 classes :-

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 {};

有时,我喜欢直接访问特定的底层证券:-

Dog* dogPtr; /** some ini ...*/ dogPtr->getWalkUnderlying()->stamina=10;

有时,我想以更抽象的方式访问 "some other functions" :-

dogOPtr->runNow();  //a custom function within WalkableO

我使用虚拟继承,因为如果我重新设计,例如每个 WalkableO 都是 HasHpO,我可以像下面这样编辑代码。
我什至不需要更改 Dog 代码:-

struct WalkableO: Crtp<WalkableO,Walkable>, virtual HasHpO{/*something*/};

Dog 本身,可以是 BullDogTigerDog 等基础 class

遗憾的是,您声明新函数的选择非常有限。

在这种情况下,您要引入一个新的 identifier. After preprocessing, an identifier can only be introduced by a declaration. Under your constraints, the only three relevant kinds of declarations are simple-declarations, function-definitions, and template-declarations (on top of a declaration, which has to be a simple-declaration or function-definition in this case since it should declare a function). In a template-declaration, the only name(s) you declare is(are) the name(s) declared in the underlying simple-declaration or function-definition, so we are basically limited to simple-declarations and function-definitions. The names introduced by a simple-declaration or a function-definition are specified in its declarator,因此无法指定新的 标识符 并自动声明它。

换句话说,在C++中预处理后没有办法“透明地”传递待声明的标识符。因此,我认为您尝试做的事情是不可能的。您必须要么使用宏,要么自己声明函数。