【问题标题】:CRTP casting specificsCRTP 铸造细节
【发布时间】:2014-12-10 18:19:15
【问题描述】:

从一个基本的 CRTP 开始,核心概念是 this 指针转换 -

#include "stdafx.h"
#include <iostream>

using namespace std;

template<class T>
class A
{
 public:

   void a0(){ static_cast<B*>(this)->a2();  }
   void a2(){ cout << "a2 base" << endl; }
};

class B: public A<int>//<int>
{
 public:
   void a1(){ a0(); }
   void a2(){ cout << "a2 derived" << endl; }
};

int _tmain(int argc, _TCHAR* argv[])
{

   B b;
   b.a1();
   return 0;
}

如果 A 不是模板,为什么强制转换失败? (MSVC:错误 C2440:'static_cast':无法从 'A *const' 转换为 'B *')

或者反过来,如果它一个模板,为什么它会起作用。

class B;
class A
{
 public:

   void a0(){ static_cast<B*>(this)->a2(); }
   void a2(){ cout << "a2 base" << endl; }
};

class B: public A
{
 public:

   void a1(){ a0(); }
   void a2(){ cout << "a2 derived" << endl; }
};

可能与模板实例化的时间有关,但我对细节很好奇。

【问题讨论】:

    标签: c++ templates crtp


    【解决方案1】:

    不是模板实例化的问题,而是定义顺序的问题。

    在声明类 A 时,类 B 仍然未知,因此,您不能要求编译器验证 static_cast 或 dynamic_cast。那时只有 reinterpret_cast 或 C 风格的转换是有效的。

    但是很容易解决:在 B 声明后拒绝a0定义

    class B;
    class A
    {
     public:
    
       void a0();
       void a2(){ cout << "a2 base" << endl; }
    };
    
    class B: public A
    {
     public:
       void a1(){ a0(); }
       void a2(){ cout << "a2 derived" << endl; }
    };
    
    void A::a0() {
        static_cast<B*>(this)->a2();
    }
    

    这样,B 已经被声明并且 static_cast 被接受了。

    【讨论】:

      【解决方案2】:
      • 如果A 不是模板,则转换失败,因为static_cast 允许多种转换类型,并且由于它不知道AB 之间的关系,所以转换失败。
      • 仅由于 MSVC 中的错误,模板案例中的转换成功。由于B 是一个非依赖类型名称,它的行为应该与非模板情况相同。然而,MSVC 不正确地阻止了检查,直到它知道AB 之间关系的类型的实例化点。 (我尝试在 g++ 上编译,但确实失败了)。

      另外请注意,您所做的根本不是 CRTP。在普通的 CRTP 中,您可能希望转换为 T* 而不是 B*,然后应该可以正常编译。我还假设您的意思是 class B: public A&lt;B&gt; 而不是 class B: public A&lt;int&gt;

      【讨论】:

      • 太好了,谢谢。代码是 sic - 所以关键点是传递类型以使 static_cast 工作。对不起,我没有代表 - 两个答案都很好,所以我必须任意接受一个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多