通过多级继承从模板子类调用基类的模板方法

c++: Calling a template method of a base class from a template child class though multilevel inheritance

本文关键字:调用 子类 基类 模板方法 多级 继承      更新时间:2023-10-16

我正在寻找从子类D中调用基类a的方法,该子类D通过C:: a和B:: a继承它

template <class PType>
class A
{
public:
    template <class ChildClass>
    void Func( void )
    {
        std::cout << "Called A<PType>::Func<ChildClass>" << std::endl;
    }
};
template <class PType>
class B : public A<PType>
{
};
template <class PType>
class C : public A<PType>
{
};
class D : public B<int>, public C<int>
{
public:
    D()
    {
        static_cast<B<int>*>( this )->A<int>::Func<D>();
        static_cast<C<int>*>( this )->A<int>::Func<D>();
    }
};

按预期工作,D在初始化时使用子类的模板参数调用B::A::Func和C::A::Func。但是,当D是模板类时,这似乎不起作用。

template <class PType>
class D2 : public B<PType>, public C<PType>
{
public:
    D2()
    {
        //expected primary-expression before ‘>’ token
        //expected primary-expression before ‘)’ token
        static_cast<B<PType>*>( this )->A<PType>::Func< D2<PType> >();
        static_cast<C<PType>*>( this )->A<PType>::Func< D2<PType> >();
    }
};

问题似乎是模板参数D2到Func,但不能找出它超出了。

当您使用的名称的值/type/template状态依赖于template类型参数时,您必须手动为编译器消除歧义。

这是为了使解析容易得多,并且能够在将类型传递给template之前很久就完成。

您可能认为这显然是template函数调用,但<>可以是比较,模板函数可以是值或类型或其他。

默认情况下,这些依赖的名称被假定为值。如果你想让他们把一个作为一个类型,使用typename。如果您想将其中一个作为模板,请使用template作为关键字。

所以像这样:

   static_cast<B<PType>*>( this )->template A<PType>::template Func< D2<PType> >();

现在,当您与完全实例化的template交互时,这是不需要的。所以:

   static_cast<B<int>*>( this )->A<int>::Func< D2<PType> >();

由一个完全实例化的template类型B<int>组成,因此A的类别不再依赖于(本地未确定的)template参数。同样,->A<int>是一个完全实例化的template类型,因此::Func不再依赖于(本地未确定的)template参数。