有许多理由不使用typeid
。除了使用type_info
成员(实现定义的行为)之外,通常(总是?)可以使用其他C ++语言功能提供类似的功能,例如:重载,虚函数等。
那么,排除依赖于实现定义行为的用法,是否有人有一个真实世界的例子,其中typeid
是最佳解决方案?
答案 0 :(得分:17)
因此,排除依赖于实现定义行为的用法,是否有人有一个真实世界的例子,其中typeid是最佳解决方案?
我有时在调试输出中使用它,以验证传递给我的函数的模板参数确实是给定类型。这在我的情况下是有道理的,因为传递给我的函数的实际模板参数是由专门的元函数生成的,我想确保使用正确的元函数。
答案 1 :(得分:14)
当实现多方法(或多个分派)时,从例如实际呼叫中选择实际呼叫。地图,使用std::type_info*
作为关键字。
答案 2 :(得分:14)
boost::any
使用typeid
来实施any_cast
。
template<typename T> any_cast(const any& other) {
if(typeid(T) != other.type()) throw bad_any_cast();
//...actual cast here...
}
你不能确定T
是多态的,所以dynamic_cast
是不可能的,而boost::any
调用中的封闭类型现在已经丢失,所以没有其他演员阵容可以提供任何类型的安全。
答案 3 :(得分:7)
编写一个动态树,您可以在树的运行时修改结构中,每个链接中有不同类型的树,它需要typeid。 dynamic_cast是不够的。
编辑:以下是一些细节:
class I {
public:
virtual std::string type() const=0;
virtual void *value() const=0;
};
template<class T>
class Impl : public I
{
public:
Impl(T t) : t(t) { }
std::string type() const { return typeid(T).name(); }
void *value() const { return &t; }
private:
T t;
};
然后用这些构建一棵树:
template<class Node, class Link>
class Tree { };
链接类型为I *接口...由于上述适用于T1,T2,T3,T4类型的任何值,因此对于任何函数T-> T1,T->,我们也可以使用类似的类。 T2,T-> T3,T-> T4,并使用该函数类型作为树的节点。现在你在动态树中描述了正确的表达式。
答案 4 :(得分:2)
您可以使用typeid
来比较两个对象的实际类型。如果你想检查两个对象的相等性,可能会很有用,并且首先要确保它们的类型完全相同(虽然我必须说我没有看到这样做很多,所以可能有一个很好的理由为什么这不是一个好主意......)。
答案 5 :(得分:2)
我用它在我的catch all handler中探测异常的类类型。
// fudge vtable existence (thrown exceptions must have one)
class StubException
{
virtual ~StubException();
};
.....
catch(...)
{
StubException *e = getExceptionObject(); // compiler/rt specific
std::string s = typeid(e).name();
...
throw;
}
函数getExceptionObject()
是小型实用程序库的一部分,我错误地访问有关异常的其他信息。当一个函数抛出一个我应该抓住但却没有的异常时,它会非常方便。多年来,它确实挽救了很多挫折感,因为我立即知道需要覆盖的异常类型。