如何在内部使模板类型更具体以帮助内容辅助?
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"
}