首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有类型的逗号操作符

问带有类型的逗号操作符
EN

Stack Overflow用户
提问于 2014-06-06 08:19:20
回答 2查看 792关注 0票数 15

我当时在学习http://www.justsoftwaresolutions.co.uk/articles/genericptr.pdf。我对第4节有些困惑。有一种说法是

仅当结果类型为多态类类型的lvalue时,才计算作为参数提供给type if运算符的表达式。

与此相关的示例代码是:

代码语言:javascript
复制
template<typename T>
  void* startOfObject(T* p) {
  void* q=static_cast<void*>(p);
  typeid(q=dynamic_cast<void*>(p),*p); // This line
  return q;
}

这意味着如果结果类型是多态类类型的l值,则将对q=dynamic_cast<void*>(p)进行评估。结果意味着评估dynamic_cast<void*>(p)的结果(我猜),因此dynamic_cast必须在任何情况下应用。这些文章声明(据我理解),如果p不是多态的,那么dynamic_cast就不会被应用,但是为什么呢?在应用之前,如何知道结果是否是多态的?如果有人详细描述如何执行完整的语句,这将是有帮助的。

另一种说法是

如果p为NULL,还会出现一个问题--类型将抛出std::坏的强制转换。

我看到的问题是,如果p是NULL,则取消引用,而不是使用typeid (虽然它可能抛出bad_typeid,但这不是因为转换)。dynamic_cast将返回一个类型为void*的NULL指针,如果p是NULL,那么typeid应该能够推断类型信息。是打错了,还是我漏掉了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-06 08:56:47

从本质上讲,编写以下代码是一种奇妙的技巧

代码语言:javascript
复制
if (T is polymorphic)
  return dynamic_cast<void*>(p);
else
  return static_cast<void*>(p);

使用的诀窍是,typeid(expr)是通过两种方法中的一种进行评估的。如果编译器确定expr具有非多态类型,则继续使用它的静态类型。但是,如果expr具有动态类型,它将在运行时计算expr。因此,逗号运算符之前的赋值是计算当且仅当逗号后面的*p是多态的。

由于这个原因,空的情况很复杂。如果T不是多态的,那么typeid(*p)在编译时被编译器替换,运行时空指针根本不重要。如果T是多态的,则适用对空指针取消引用的特殊处理,并且该特殊处理声明抛出std::bad_typeid异常。

票数 11
EN

Stack Overflow用户

发布于 2014-06-06 08:40:15

逗号运算符具有从左到右的结合性,并从左到右求值.这意味着表达式q=dynamic_cast<void*>(p),*p的结果是*p。因此,只有在*p类型是多态的情况下,才会对动态强制转换进行评估。

关于NULL问题,标准声明:

当类型is应用于类型为多态类类型(10.3)的lvalue表达式时,结果引用一个type_info对象,该对象表示lvalue所引用的最派生对象(1.8) (即动态类型)的类型。如果通过将一元*运算符应用于指针获得lvalue表达式,且指针为空指针值(4.10),则typeid表达式将抛出bad_typeid异常(18.5.3).

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

https://stackoverflow.com/questions/24077253

复制
相关文章

相似问题

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