何时使用'typeid'是最佳解决方案?

时间:2011-07-19 17:02:33

标签: c++ typeid

有许多理由不使用typeid。除了使用type_info成员(实现定义的行为)之外,通常(总是?)可以使用其他C ++语言功能提供类似的功能,例如:重载,虚函数等。

那么,排除依赖于实现定义行为的用法,是否有人有一个真实世界的例子,其中typeid是最佳解决方案?

6 个答案:

答案 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()是小型实用程序库的一部分,我错误地访问有关异常的其他信息。当一个函数抛出一个我应该抓住但却没有的异常时,它会非常方便。多年来,它确实挽救了很多挫折感,因为我立即知道需要覆盖的异常类型。