Make the template type more specific (T => Defined <X>) to help support content

How to make the template type more specific to help help?

template<class T>class B{ //note: in real case, it has more template parameter public: void f(){} }; template<class B1>class C{ //<-- I know for sure that B1 derived from "B<something>". B1* b; void test(){ b-> ^ ctrl+space doesn't show f() } }; 

My bad decision is to create a specialized specialization in class C , but this confuses the content help in a different way.

Below is another workaround, but it is rather tedious.
I have to reflect the template argument in B and use that reflex in C one by one.

 template<class T>class B{ public: using reflectiveT=T; /* other T eg reflectiveT2=T2 , ... */ public: void f(){} }; template<class B1>class C{ using BX=B<B1::reflectiveT>; //B<B1::reflectiveT1,..T2,...T3> ... tedious BX* b; void test(){ b-> ^ ctrl+space will show f() } }; 

Problems:

  • It suffers from a security issue when I want to reorganize B to have more / less template arguments later.
  • If BX is the class that got from B<something> , BXT will be! = BX .

I dream of something like:

 template<class B1>class C{ using BX=B<...> as base of B1; //???? }; 

I can also rely on content help, but it helps me a lot to code very complex classes.

Edit

I cannot just pass Args inside B as a parameter to the C template, because C may not work correctly.

For example, B<D>::callback will be a call instead of D::callback in the code below ( demo ): -

 class x{}; template<class T>class B{ public: static void callback(){ std::cout<<"B<D>::callback()"; } }; class D : public B<D>{ // public: static void callback(){ std::cout<<"D::callback()"; } }; template<class... Args>class C{ using BX=B<Args...>; BX* b; public: void test(){ BX::callback(); //^ will invoke B<D>::callback (wrong) // instead of D::callback } }; int main(){ C<D> c; c.test(); //print "B<D>::callback()" } 

Edit: Simplify the question.

+5
source share
1 answer

You can separate the implementation and interface for each function:

 #include <iostream> // Base class with default implementations and common interface template<class T> class B { static void callback_impl() { std::cout<<"B<T>::callback()\n"; } void f_impl() { std::cout << "B<T>::f()\n"; } public: static void callback() { T::callback_impl(); } void f() { static_cast<T*>(this)->f_impl(); } }; class D1 : public B<D1>{ // D1 overrides callback friend class B<D1>; static void callback_impl(){ std::cout<<"D1::callback()\n"; } }; class D2 : public B<D2> { // D2 overrides f friend class B<D2>; void f_impl() { std::cout << "D2::f()\n"; } }; template<class... Args>class C{ using BX=B<Args...>; BX b; public: void test(){ BX::callback(); bf(); } }; int main(){ C<D1> c1; c1.test(); //print "D1::callback()\nB<T>::f()\n" C<D2> c2; c2.test(); //print "B<T>::callback()\nD2::f()\n" } 
+4
source

All Articles