crtp父级对姐妹类的访问

crtp parent access to sister class

本文关键字:访问 姐妹 crtp      更新时间:2023-10-16

我有一个名为base的类。这个类是不可访问的(我指的是源代码),因为它是第三方类。这个类有一个方法,我想从(父)姐妹(比如说叔叔)类访问它。

class base {
public:
  void do_something() {
    std::cout << "base1::do_something" << std::endl;
  }
};

我有另一个父类,它是通过使用crtp访问子类的成员而创建的:

template<typename crtpT>
class crtp {
public:
  void foo() {
    std::cout << "crtp::foo" << std::endl;
    static_cast<crtpT*>(this)->bar();
    //static_cast<crtpT::base_type*>(this)->do_something();
    // how do i access base::bar
  }
};

最后,一个从两者继承的子类:

template<typename baseT>
class child : public baseT, public crtp<child<baseT> > {
public:
  typedef baseT base_type;
  void bar() {
    std::cout << "child::bar" << std::endl;
  }
};

main.cpp:

int main(int argc, char* argv[]) {
  child<base> ch;
  ch.do_something();
  ch.foo();
  ch.bar();
  return 0;
}

现在我的问题是,我需要从crtp-类访问do_something。这可能吗?

静态广播不起作用。我认为在生成crtp类时,编译器对基类一无所知。crtp类必须是类子类的父类,因为许多其他类都是从它派生的。否则,我可能会使用对姐妹类的委托。


编辑:

我可以在我的孩子内部做第二个bar方法,但这不是很好,因为我必须为基类中的所有方法编写包装器。

template<typename baseT>
class child : public baseT, public crtp<child<baseT> > {
public:
  typedef baseT base_type;
  void bar() {
    std::cout << "child::bar" << std::endl;
  }
  void bar2() {
    base_type::do_something();
  }
};

并呼叫:

static_cast<crtpT*>(this)->bar2();

static_cast:[expr.static.cast]/11

类型为"pointer to cv1 B"的prvalue,其中B是类类型,可以转换为类型为"pointer to cv2 D"的prvalue,其中D是从B[…]派生的类

因此,您需要将crtp<...>*转换为子类child*,然后甚至可以使用隐式转换为base,例如

crtpT::base_type* p = static_cast<crtpT*>(this);