通过CRTP类继承的模板化派生类,访问基类成员对象

Templatized derived class inheriting through CRTP class, access to base class member object

本文关键字:派生 访问 基类 成员对象 CRTP 继承 通过      更新时间:2023-10-16

如果我试图从继承层次结构另一端的模板类调用基类成员的成员函数,

class memberobj {public: void bar(){}};
class basis {public: memberobj foo;};
template<class Base, class Derived>
class crtp : public Base { /* ... */ };
template<class Option>
class choice : crtp< basis, choice<Option> > {
  using basis::foo;
 public:
  void test () {foo.bar();}
};
class someoption {};
int main() {
  choice<someoption> baz;
  baz.test();
  return 0;
}

我收到这个错误消息:

g++-4.6 -o bin/crtptest crtptest.cpp
crtptest.cpp: In member function ‘void choice<Option>::test()’:
crtptest.cpp:12:21: error: ‘class basis’ has no member named ‘bar’
make: *** [bin/crtptest] Error 1

虽然bar显然是的成员,是basis的成员,而不是basis本身的成员
这种情况不会发生在非模板的final类中(其中有很多已经在使用,都是通过crtp中间类派生的;所以我不想对此做任何更改),也不会发生在直接从basis派生的模板类中。

这里怎么了?

你做得不对:

 using basis::foo; //wrong way

什么是basis?它不是choice的基类。你应该这样做:

typedef crtp< basis, choice<Option> > base;
using base::basis::foo;

因为crtp< basis, choice<Option> >choice类的基,而foo通过其基类成为choice的成员。所以有一个微妙的区别。

现在它起作用了:http://ideone.com/RPnyZ