template <class T> void checkObject(T genericObject)
{
MyClassA* a = dynamic_cast<MyClassA*>(genericObject);
if (a != NULL)
{
//we know it is of type MyClassA
}
MyClassB* b = dynamic_cast<MyClassB*>(genericObject);
if (b != NULL)
{
//we know it is of type MyClassB
}
}
这样的事情可能吗?我们有模板类型,但我们想知道它的实际类型?
答案 0 :(得分:7)
在模板世界中,您可能只想为每种类型专门化模板,而不是进行运行时检查,即
template<typename T>
void foo(T obj);
template<>
void foo<MyClassA>(MyClassA obj) {
}
template<>
void foo<MyClassB>(MyClassB obj2) {
}
这将允许编译器在编译时通过推断你的args来生成正确的模板。
注意这仅根据实例的静态类型解析,即没有编译时知道您的变量是MyClassC
,它继承自MyClassB
,因此应该使用通用表格。所以这不起作用:
MyClassC* cinstance = new MyClassC();
foo(cinstance); //compiler error, no specialization for MyClassC
一般来说,这指向编译时和运行时多态是非常不同的系统的一般规则。模板严格地处理静态类型领域而不知道继承。这可能会让来自Java / C#的人们感到惊讶,这些人在这两个功能之间实现了更加无缝的集成。
对于类的功能的运行时专业化,您的选项是
答案 1 :(得分:4)
可能但MyClassA
和MyClassB
必须至少有一个虚拟成员函数才能使dynamic_cast
正常工作。我也相信你实际上想要在函数的签名中使用(T* genericObject
)而不是T genericObject
(否则就没有意义)。
基于模板特化的解决方案适用于 静态多态,但我相信问题是如何启用 运行时检测输入的类型。我想这个模板是用一个指针调用的,该指针的类型是MyClassA
的超类或 MyClassB
的超类。 模板专业化将失败在这种情况下提供正确的答案。
无论如何,我有一种强烈的感觉,你正试图做错事来达到你想要达到的目标(不管它是什么)。当您发布此类问题时,我建议您明确哪里,您的目标;这个可能只是沿着错误路径的障碍。
答案 2 :(得分:1)
是的,这是可能的。请注意,动态转换在运行时发生,模板生成代码在durign编译。因此,该函数仍将生成,但会在运行时针对您描述的情况进行检查。
编辑:看看Doug T.的答案,找到正确的做法。