c – 奇怪的static_cast技巧?

前端之家收集整理的这篇文章主要介绍了c – 奇怪的static_cast技巧?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在阅读Qt源代码时,我遇到了这个宝石:
template <class T> inline T qgraphicsitem_cast(const QGraphicsItem *item)
{
    return int(static_cast<T>(0)->Type) == int(QGraphicsItem::Type)
        || (item && int(static_cast<T>(0)->Type) == item->type()) ? static_cast<T>(item) : 0;
}

注意static_cast< T>(0) – > Type?我一直在使用C多年,但从未见过0在static_cast之前使用.这段代码是做什么的,它是安全的吗?

背景:如果从QGraphicsItem派生,您将声明一个名为Type的唯一枚举值,并实现一个名为type的虚拟函数,返回它,例如:

class Item : public QGraphicsItem
{
public:
  enum { Type = MAGIC_NUMBER };
  int type() const { return Type; }
  ...
};

你可以这样做:

QGraphicsItem* item = new Item;
...
Item* derivedItem = qgraphicsitem_cast<Item*>(item);

这可能有助于解释static_cast正在尝试做什么.

解决方法

这看起来像一个非常可疑的方式来静态地声明模板参数T有一个类型成员,然后验证其值是预期的魔术数字,就像你说的那样你应该做的.

因为Type是一个枚举值,所以不需要这个指针来访问它,所以static_cast< Item>(0) – > Type检索Item :: Type的值,而不实际使用指针的值.所以这有效,但是可能是未定义的行为(取决于您对标准的看法,但是IMO是一个坏主意),因为代码使用指针dereference操作符( – >)来引用NULL指针.但是,我不能想像为什么这更好的只是Item :: Type或模板T :: Type – 也许这是旧的代码设计工作在旧的编译器与不良的模板支持,无法解决什么T :: Type应该是意思

尽管如此,最终的结果是在编译时由于bool没有类型成员枚举而导致的代码如qgraphicsitem_cast< bool>(ptr)将失败.这比运行时检查更可靠和便宜,即使代码看起来像一个黑客.

猜你在找的C&C++相关文章