考虑将对象作为参数并打印其类型的问题:
#include <iostream>
class A { };
class B : public A { };
class C : public A { };
class D : public C, public B { };
using namespace std;
template<class T>
void print_type(T* info)
{
if(dynamic_cast<D*>(info))
cout << "D" << endl;
else if(dynamic_cast<C*> (info))
cout << "C" << endl;
else if(dynamic_cast<B*>(info))
cout << "B" << endl;
else if(dynamic_cast<A*> (info))
cout << "A" << endl;
}
int main(int argc, char** argv)
{
D d;
print_type(&d);
return 0;
}
它给出了以下错误:“从派生类'D'到基类的模糊转换。”
但是我没有看到歧义在哪里:如果在main(d)中声明的对象是D类型,为什么它不能直接转换为类型A?
另外,如果我传递一个类型字符串的参数,我当然会得到其他错误:
'std::basic_string<char>' is not polymorphic
在Java for generics中有语法:<T extends A>
;在这种情况下,它会很有用。如何使用模板在C ++中创建类似的东西?
我已经用这种方式修改了代码:
#include <iostream>
#include <vector>
class A { };
class B : virtual public A { };
class C : virtual public A { };
class D : public C, public B { };
using namespace std;
template<class T>
void print_type(T* info)
{
if(dynamic_cast<D*>(info))
cout << "D" << endl;
else if(dynamic_cast<C*> (info))
cout << "C" << endl;
else if(dynamic_cast<B*>(info))
cout << "B" << endl;
else if(dynamic_cast<A*> (info))
cout << "A" << endl;
}
int main(int argc, char** argv)
{
string str;
print_type(&str);
return 0;
}
但我仍然收到错误: 'std::basic_string<char>' is not polymorphic
答案 0 :(得分:7)
首先,这不是模板问题。如果您删除了该模板,只需让print_type
获取D*
,您就会看到错误仍然存在。
发生的事情是你不使用虚拟继承,因此你会遇到这种情况:
A A
| |
B C
\ /
D
dynamic_cast不知道您正在引用的 A
。
实现这一目标:(我认为这是你想要的)
A
/ \
B C
\ /
D
...你应该使用 virtual inheritance ,ergo:
class A
{
};
class B : virtual public A
{
};
class C : virtual public A
{
};
class D : public C,public B
{
};
...现在它编译没有问题:)(请记住虚拟继承是邪恶的)
答案 1 :(得分:2)
这称为deadly diamond of death,或简称为钻石问题。 A的“路径”可以通过B或C,因此可能存在矛盾。
此外,模板的想法是使其成为通用的,而不是类型感知的。模板本身不是编译代码,而是根据其使用进行编译。这很像一个大宏。
答案 2 :(得分:0)
考虑将对象作为参数并打印它的类型的问题:
叹气......使用RTTI。
#include <iostream>
#include <string>
#include <typeinfo>
template<class T> void print_type(const T& info){
std::cout << typeid(info).name() << std::endl;
}
int main(int argc, char** argv){
D d;
int a = 3;
std::string test("test");
print_type(d);
print_type(a);
print_type(test);
return 0;
}