typeid不适用于非静态成员函数 [英] typeid doesn't work with non-static member function

查看:87
本文介绍了typeid不适用于非静态成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

clang不会编译下面对typeid的第三次调用(请参见实时示例).但是在§5.2.8中我看不到任何东西不允许这样做,特别是当我们认为表达式B::f不是多态类类型的glvalue时(请参见第3段).同样,根据本段,表达式B::f是未求值的操作数,因此,调用typeid(B::f)应该进行编译.请注意,GCC不会编译对以下typeid的任何调用:

clang doesn't compile the third call to typeid below (see live example). But I can't see anything in §5.2.8 that disallows this, specially when we consider that the expression B::f is not a glvalue of polymorphic class type (see paragraph 3). Also, according to this paragraph the expression B::f is an unevaluated operand, and as such, the call typeid(B::f) should compile. Note that GCC doesn't compile any of the calls to typeid below:

#include <iostream>
#include <typeinfo>

struct A{ int i; };
struct B{ int i; void f(); };

int main()
{
    std::cout << typeid(A::i).name() << '\n';
    std::cout << typeid(B::i).name() << '\n';
    std::cout << typeid(B::f).name() << '\n';
}

推荐答案

据我所知clang是正确的,使用非静态成员(如果它是数据成员)仅在未评估的上下文中有效.因此,看起来gcc在前两种情况下是不正确的,但是gccsizeofdecltype的情况下也可以正常工作.

As far as I can tell clang is correct, using a non static member is only valid in an unevaluated context if it is a data member. So it looks like gcc is incorrect for the first two cases, but gcc works correctly in the case of sizeof and decltype which also have unevaluated operands.

来自草稿C ++ 11标准部分5.1.1 [expr.prim.general] :

一个id表达式,表示一个非静态数据成员或非静态 类的成员函数只能使用:

An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

并包括以下项目符号:

如果该id-expression表示一个非静态数据成员,并且它出现 在未评估的操作数中. [示例:

if that id-expression denotes a non-static data member and it appears in an unevaluated operand. [ Example:

struct S {
    int m;
};
int i = sizeof(S::m); // OK
int j = sizeof(S::m + 42); // OK 

-结束示例]

其余的项目符号不适用,如下所示:

The rest of the bullets do not apply, they are as follows:

  • 作为类成员访问权限(5.2.5)的一部分,其中对象表达式引用成员的类 61 或从该成员类派生的类 类,或者
  • 形成指向成员(5.3.1)的指针,或
  • 在用于该类或从该类派生的类的构造函数的内存初始化程序中(12.6.2),或者
  • 在括号或相等初始化程序中,用于该类或从该类派生的类的非静态数据成员(12.6.2),或者
  • as part of a class member access (5.2.5) in which the object expression refers to the member’s class61 or a class derived from that class, or
  • to form a pointer to member (5.3.1), or
  • in a mem-initializer for a constructor for that class or for a class derived from that class (12.6.2), or
  • in a brace-or-equal-initializer for a non-static data member of that class or of a class derived from that class (12.6.2), or

我们知道5.2.8部分未计算操作数,

We know that operand is unevaluated from section 5.2.8 which says:

当typeid应用于除a的glvalue以外的表达式时 多态类类型,表达式是一个未求值的操作数 (第5条).

When typeid is applied to an expression other than a glvalue of a polymorphic class type, [...] The expression is an unevaluated operand (Clause 5).

从语法中我们可以看到 id-expression unqualified-id qualified-id :

We can see from the grammar that an id-expression is either an unqualified-id or a qualified-id:

id-expression:
    unqualified-id
    qualified-id

更新

提交了gcc 错误报告:typeid不允许ID表达式表示一个非静态数据成员.

这篇关于typeid不适用于非静态成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆