使模板类型更具体(T =>某些<X>)以帮助内容辅助

jav*_*ver 5 c++ intellisense templates visual-studio c++14

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

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()
    }
};
Run Code Online (Sandbox Code Playgroud)

我糟糕的解决方法是在课堂上创建模板专业化C,但它会以另一种方式混淆内容辅助.

下面是另一种解决方法,但它非常繁琐.
我必须反映模板参数BC逐一使用这种反射.

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()
    }
};
Run Code Online (Sandbox Code Playgroud)

问题:

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

我的梦想是这样的:

template<class B1>class C{ 
    using BX=B<...> as base of B1;   //????
};
Run Code Online (Sandbox Code Playgroud)

我可能过于依赖内容辅助,但它极大地帮助我编写非常复杂的类.

编辑

我不能只把Args内部B作为模板参数传递C,因为C可能会出错.

例如,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()"
}
Run Code Online (Sandbox Code Playgroud)

编辑: 简化问题很多.

cht*_*htz 4

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

#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"
}
Run Code Online (Sandbox Code Playgroud)