将基类模板的这种类型强制转换为其派生类 [英] Typecasting `this` of a base class template to its derived class

查看:281
本文介绍了将基类模板的这种类型强制转换为其派生类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码的简化版本如下:

  template< class T& 
struct Base
{
void SayHello(T * aDerived)
{
}

void SaySomething()
{
SayHello(this); //这是错误发生的地方
}
};

struct Derived:public Base<派生>
{
};

int main(int argc,const char * argv [])
{
Derived iDerived;
iDerived.SaySomething();
}

它不会在上编译SayHello

$

 无法初始化类型为'Derived *'的参数

b $ b,其类型为Base< Derived> *'

现在编译器抱怨这是有意义的,虽然在我看来有点蠢它不会抱怨如果我删除这行:

  iDerived.SaySomething(); 

无论如何,问题可以通过执行显式类型转换来解决,例如:

  SayHello((T *)this); 

事实是,我的实际代码结束了许多这些类型转换,只需在 Base 中包含一些可以自动类型转换为其模板类( T )。 p>

operator = 我在吗?有人可以提供一个代码示例如何做吗? 此问题表明我可以执行以下操作:



演员总是在 T * 之间。

 运算符T *()
{
return(T *)this;
}

但错误仍然存​​在。

解决方案

您可以添加一个帮助函数,返回 this downcast到派生类型

 模板< class T> 
struct Base
{
void SayHello(T * aDerived)
{
}

void SaySomething()
{
SayHello(derived_this());
}

private:
T * derived_this()
{
return static_cast< T *>
}

您可能还需要一个 const overload:

  const T * derived_this()const 
{
return static_cast< const T *>(this);
}

您可以添加隐式转换运算子,我不会推荐它:

  operator T *(){return static_cast< T *>(this); } 

隐式转换削弱了类型系统,可能是错误的来源, derived_this()更清晰,更安全。


A simplified version of my code looks like so:

template <class T>
struct Base
{
    void SayHello( T* aDerived )
    {
    }

    void SaySomething()
    {
        SayHello( this ); // This is where the error happens
    }
};

struct Derived : public Base< Derived >
{
};

int main(int argc, const char * argv[])
{
    Derived iDerived;
    iDerived.SaySomething();
}

And it won't compile on the SayHello( this ) line with this error message:

Cannot initialize a parameter of type 'Derived *'
with an rvalue of type 'Base<Derived> *'

Now it makes sense for the compiler to complain about this, although it seems to me somewhat stupid it doesn't complain if I remove this line:

iDerived.SaySomething();

Anyhow, the problem can be solved by doing an explicit typecast, like so:

SayHello( (T*)this );

The thing is that my actual code ends up with many of these typecasts, and it seems to me reasonable to just include in Base something that will allow it to be typecasted automatically to its template class (T).

Is it the operator= I'm after? Can someone provide a code sample to how this is done? This Question suggests I can do something like:

The cast is always between this and T*.

operator T*()
{
    return (T*)this;
}

But the error remains.

解决方案

You could add a helper function that returns this downcast to the derived type

template <class T>
struct Base
{
    void SayHello( T* aDerived )
    {
    }

    void SaySomething()
    {
        SayHello( derived_this() );
    }

private:
    T* derived_this()
    {
        return static_cast<T*>(this);
    }

You might also want a const overload:

    const T* derived_this() const
    {
        return static_cast<const T*>(this);
    }

You could add an implicit conversion operator, but I would not recommend it:

    operator T*() { return static_cast<T*>(this); }

Implicit conversions weaken the type system and can be a source of bugs, I think an explicit function such as derived_this() is clearer and safer.

这篇关于将基类模板的这种类型强制转换为其派生类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆