c++ - 测试一个类是否是多态的

标签 c++ templates polymorphism typeid

我们有一个子项目“commonUtils”,它有许多在父项目中使用的通用代码片段。 我看到的一个这样有趣的东西是:-

/*********************************************************************
If T is polymorphic, the compiler is required to evaluate the typeid 
stuff at runtime, and answer will be true.  If T is non-polymorphic, 
the compiler is required to evaluate the typeid stuff at compile time, 
whence answer will remain false
*********************************************************************/
template <class T> 
bool isPolymorphic() { 
   bool answer=false; 
   typeid(answer=true,T()); 
   return answer; 
}

我相信评论并认为它是一个非常有趣的模板,尽管它不是 在整个项目中使用。出于好奇,我试过这样使用它......

class PolyBase {
public:
   virtual ~PolyBase(){}
};

class NPolyBase {
public:
   ~NPolyBase(){}
};


if (isPolymorphic<PolyBase>())
  std::cout<<"PolyBase = Polymorphic\n";
if (isPolymorphic<NPolyBase>())
  std::cout<<"NPolyBase = Also Polymorphic\n";

但是这些都不会返回 true。 MSVC 2005 没有发出警告,但 Comeau 警告 typeid 表达式无效。 C++ 标准中的第 5.2.8 节并没有像评论所说的那样说明任何内容,即 typeid 在编译时针对非多态类型进行评估,在运行时针对多态类型进行评估。

1) 所以我猜评论是误导性的/明显错误的,或者因为这段代码的作者是一位相当资深的 C++ 程序员,我是否遗漏了什么?

2) OTOH,我想知道我们是否可以使用某种技术来测试一个类是否是多态的(至少有一个虚函数)?

3) 人们什么时候想知道一个类是否是多态的?胡乱猜测;使用 dynamic_cast<void*>(T) 获取类的起始地址(因为 dynamic_cast 仅适用于多态类)。

等待您的意见。

提前致谢

最佳答案

我无法想象如何使用 typeid 来检查该类型是多态的。它甚至不能用来断言它是,因为 typeid 将适用于任何类型。 Boost 有一个实现 here .至于为什么有必要——我知道的一个例子是 Boost.Serialization 库。如果你正在保存非多态类型,那么你可以直接保存它。如果保存多态的,则必须使用 typeid 获取其动态类型,然后为该类型调用序列化方法(在某个表中查找)。

更新:看来我真的错了。考虑这个变体:

template <class T> 
bool isPolymorphic() { 
    bool answer=false;
    T *t = new T();
    typeid(answer=true,*t); 
    delete t;
    return answer; 
}

这实际上确实如名称所暗示的那样起作用,完全符合您原始代码片段中的评论。如果 typeid 中的表达式“不指定多态类类型的左值”(std 3.2/2),则不会对其进行评估。因此,在上述情况下,如果 T 不是多态的,则不会评估 typeid 表达式。如果 T 是多态的,那么 *t 确实是多态类型的左值,因此必须计算整个表达式。

现在,您原来的示例仍然是错误的 :-)。它使用 T(),而不是 *tT() 创建 rvalue (std 3.10/6)。因此,它仍然会产生一个不是“多态类的左值”的表达式。

这是相当有趣的把戏。另一方面,它的实用值(value)有些有限——因为虽然 boost::is_polymorphic 给你一个编译时常量,但这个给你一个运行时值,所以你不能为多态和非多态类型实例化不同的代码.

关于c++ - 测试一个类是否是多态的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1107948/

相关文章:

C++模板函数错误: template-id does not match any template declaration

c++ - 无法合法转换为 'this' 指针

iterator - 如何迭代结构集合作为特征对象引用的迭代器?

c++ - 当函数属于类时未解析的重载函数类型

c++ - 在 C++ 中使用 const ArrayType 或 ConstArrayType typedef 具有 const 元素的数组

c++ - 隐藏的对话框暂时占据焦点

c# - 隐藏继承成员

c++ - 如何在 C++ 中将日期读入结构?

c++ - 同时接受const和非const参数的模板方法

java - 通过数组访问数组元素是否比通过函数获取它们更有效?