c++ - 尽管调用是在类型完整的地方完成的,但对类模板参数的 Dynamic_casting 会给出不完整的类型错误
问题描述
这是问题的代码:https
://godbolt.org/z/hK33nP6dT 下面的代码
片段还不够,完整的问题示例代码在那个 godbolt 链接中。
这是错误:
[ 33%] Building CXX object CMakeFiles/test.dir/main.cpp.o
In file included from /app/container.h:3,
from /app/main.cpp:3:
base.h: In instantiation of 'bool DerivedChecker<T>::IsValid(const BaseClass*) [with T = DerivedClass]':
base.h:13:7: required from here
base.h:15:10: error: cannot 'dynamic_cast' 'base' (of type 'const struct BaseClass*') to type 'const struct DerivedClass*' (target is not pointer or reference to complete type)
15 | return dynamic_cast<const T*>(base) != nullptr;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
我的总体目标是将 a 传递给BaseClass*
函数IsValid
并尝试dynamic_cast
将该指针指向某个模板化类型 T。然后如果可能返回 true,如果失败则返回dynamic_cast
false 。dynamic_cast
我只想看看传入的BaseClass*
指针是否可以转换为模板类型 T。
问题是dynamic_cast
由于某种原因类型不完整,即使我是IsValid
从代码中具有完整类型的位置进行调用的。我想构造我的代码,以便dynamic_cast
确实具有完整的类型,从而消除错误。
我需要DerivedChecker
在其模板类型被前向声明(不完整)的地方声明对象,然后在模板类型完整的地方IsValid
通过它们的基础虚拟调用。BaseChecker
所以一般的想法是在各种头文件中前向声明的类型用作模板参数DerivedChecker
:
class DerivedClass; //forward declared, incomplete type
BaseChecker* checker = new DerivedChecker<DerivedClass>(); //forward declared type used as template parameter, storing as a pointer to BaseChecker and using a virtual call through it later
然后在他们各自的 .cpp 文件中,我包含完成这些类型的标题,然后调用IsValid
:
class DerivedClass : public BaseClass {}; //defined, complete class
checker->IsValid(new BaseClass()); //virtual call to DerivedChecker<DerivedClass>::IsValid
这必须在不同的头文件和编译单元中完成;我不能只是将所有这些东西粉碎到一个头文件/cpp 文件中,因为DerivedChecker
将在许多地方使用许多不同的模板类型。
在我的示例中,我使用了在 中声明的前向DerivedClass
,然后在对 . 的虚拟调用之前container.h
完全定义了它。因此,当进行虚拟调用时, ,是完全定义的,但仍然抛出“目标不是完整类型的指针或引用”错误。container.cpp
DerivedChecker<DerivedClass>::IsValid
IsValid
DerivedChecker<DerivedClass>
DerivedClass
dynamic_cast
在示例代码中,base.h
包含BaseChecker
和DerivedChecker
作为BaseClass
参数的IsValid
。
container.h
是 的常见用例DerivedChecker
: 具有DerivedChecker
字段的某个类(在本例中为 class Container
),具有 in 中使用的模板类型的前向声明DerivedChecker
(在本例中,DerivedChecker<DerivedClass>
前DerivedClass
向声明为 in container.h
)。
container.cpp
将保存.container.h
中前向声明类的函数定义以及所有必要的包含container.h
。在这个例子中,我只是简单地定义DerivedClass
而container.cpp
不是为它创建另一个头文件并包含它。 在完全定义之后,定义了一个进行虚拟调用Container
的函数,并且是.container.cpp
IsValid
DerivedClass
container.cpp
main.cpp
只需设置所有这些并调用该函数。
如何保持这种使用模式,并构造代码以便dynamic_cast
在调用时访问完整类型?
解决方案
推荐阅读
- flutter - 错误:'AnimatedScale' 是从 /implicit_animations.dart' 和 'package:flutter_neumorphic/src/widget/animation/animated_scale.dart' 导入的
- javascript - AWS Amplify 托管 Nuxt 应用程序的构建不会因错误而失败
- authentication - 安全地使用 JSON Web 令牌以编程方式将用户从一个系统验证到另一个系统
- python - 如何在 tkinter 中没有文本的按钮上添加图像?
- android - 我需要帮助让我的 .XML 布局适合旧 Zebra 设备上的屏幕
- java - 如何从 USB 条码设备读取条码
- java - 如何将 JAR 文件添加到 VS 代码?
- r - 如果列中的值小于 X,则转换列的值
- javascript - 使用 JavaScript 在 iOS 上停止听写
- flutter - 在 Flutter 小部件测试中访问 GetXController