首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >`typeid`代码中`?:`的奇怪用法

`typeid`代码中`?:`的奇怪用法
EN

Stack Overflow用户
提问于 2011-07-23 04:43:09
回答 3查看 2.1K关注 0票数 60

在我正在做的一个项目中,我看到了以下代码

代码语言:javascript
复制
struct Base {
  virtual ~Base() { }
};

struct ClassX {
  bool isHoldingDerivedObj() const {
    return typeid(1 ? *m_basePtr : *m_basePtr) == typeid(Derived);
  }
  Base *m_basePtr;
};

我从未见过typeid被这样使用过。为什么它要和?:跳这种奇怪的舞,而不是只跳typeid(*m_basePtr)

编辑:在这段代码的另一个地方,我看到了这个,它看起来等同于“多余的”。

代码语言:javascript
复制
template<typename T> T &nonnull(T &t) { return t; }

struct ClassY {
  bool isHoldingDerivedObj() const {
    return typeid(nonnull(*m_basePtr)) == typeid(Derived);
  }
  Base *m_basePtr;
};
EN

回答 3

Stack Overflow用户

发布于 2011-07-23 04:59:43

我能看到的唯一效果是,1 ? X : XX作为右值,而不是普通的X,后者将是左值。对于像数组(衰减到指针)这样的东西,这对typeid()来说可能很重要,但我认为如果知道Derived是一个类,那就不重要了。也许它是从某个有价值的地方复制过来的?这将支持关于“货物狂欢节编程”的评论。

关于下面的评论,我做了一个测试,果然是typeid(array) == typeid(1 ? array : array),所以在某种意义上我是错的,但我的误解仍然可能与导致原始代码的误解相匹配!

票数 5
EN

Stack Overflow用户

发布于 2015-01-24 08:04:54

expr.typeid/2 (N3936)包含了这种行为:

typeid应用于类型为多态类类型的glvalue表达式时,结果将引用一个std::type_info对象,该对象表示glvalue引用的派生最多的对象(即动态类型)的类型。如果glvalue表达式是通过对指针应用一元*运算符获得的,并且该指针是空指针值,则typeid表达式将抛出与std::bad_typeid exception类型的处理程序匹配的类型的异常。

表达式1 ? *p : *p始终是左值。这是因为*p是一个左值,而expr.cond/4表示,如果三元运算符的第二个和第三个操作数具有相同的类型和值类别,则运算符的结果也具有该类型和值类别。

因此,1 ? *m_basePtr : *m_basePtr是一个类型为Base左值。因为Base有一个虚拟析构函数,所以它是一个多态类类型。

因此,这段代码确实是一个“当typeid应用于其类型是多态类类型的glvalue表达式时”的示例。

现在我们可以阅读上面引用的其余部分。GL值表达式是“通过将一元*运算符应用于指针而获得的”-它是通过三元运算符获得的。因此,该标准不要求在m_basePtr为null时抛出异常。

m_basePtr为null的情况下的行为将被更通用的关于取消引用null指针的规则所涵盖(这在C++中实际上是有点模糊的,但为了实际目的,我们假设它会导致未定义的行为)。

最后:为什么有人要写这篇文章?我认为好奇心的答案是到目前为止最合理的建议:使用这种构造,编译器不必插入空指针测试和代码来生成异常,因此它是一个微优化。

想必程序员要么很高兴,因为它永远不会被空指针调用,要么很高兴依赖于特定实现对空指针取消引用的处理。

票数 4
EN

Stack Overflow用户

发布于 2011-08-06 15:46:09

代码语言:javascript
复制
typeid(*m_basePtr)

无论运行时类型如何,始终返回typeid(Base)。但将其转换为表达式/临时/rvalue会使编译器给出RTTI。

问题是哪个编译器,什么时候,等等。我想GCC在早期的typeid方面有问题,但这是一个模糊的记忆。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6795890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档