如何在内部使模板类型更具体以帮助内容辅助?

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()
    }
};

我可怜的解决方法是在类C上创建模板专门化,但是它将以另一种方式混淆内容辅助。

以下是另一种解决方法,但它很繁琐。
我必须在B上反射(reflect)模板参数,并在C上一对一地使用这样的反射(reflect)。
template<class T>class B{
    public: using reflectiveT=T;
    /* other T e.g. 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()
    }
};

问题:
  • 遇到可维护性问题,
    当我想重构B以后有更多/更少的模板参数时。
  • 如果BX恰好是B<something>派生的类,则BXT将!= BX

  • 我梦for以求的东西:
    template<class B1>class C{
        using BX=B<...> as base of B1;   //????
    };
    

    我可能也依赖于内容辅助,但这极大地帮助了我编写非常复杂的类。

    编辑

    我不能只将Args内的B作为C的模板参数传递,因为C可能会执行错误。

    例如,在下面的代码( demo )中,将调用B<D>::callback而不是D::callback:-
    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()"
    }
    

    编辑:大大简化了问题。

    最佳答案

    您可以将每个函数的实现和接口(interface)分开:

    #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();
            b.f();
        }
    };
    
    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"
    }
    

    10-01 20:03
    查看更多