clang
不编译第三次调用typeid
下面(参见活生生的例子 http://coliru.stacked-crooked.com/a/e61efc069f27dc35)。但我在第 5.2.8 节中看不到任何不允许这样做的内容,特别是当我们认为表达式B::f
不是多态类类型的左值(参见第 3 段)。另外,根据本段的表达式B::f
是一个未评估的操作数,因此,调用typeid(B::f)
应该编译。注意GCC
不编译任何调用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
对于前两种情况是不正确的,但是gcc
在以下情况下可以正常工作sizeof
and decltype
其中也有未评估的操作数。
来自C++11 标准草案 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf部分5.1.1
[expr.prim.general]:
表示非静态数据成员或非静态的 id 表达式
类的成员函数只能使用:
并包括以下项目符号:
如果该 id 表达式表示非静态数据成员并且它出现
在未评估的操作数中。[ 例子:
struct S {
int m;
};
int i = sizeof(S::m); // OK
int j = sizeof(S::m + 42); // OK
—结束示例]
其余项目符号不适用,如下:
- 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
- 形成一个指向成员的指针(5.3.1),或者
- 在该类或从该类派生的类的构造函数的 mem-initializer 中 (12.6.2),或者
- 在该类或从该类派生的类的非静态数据成员的大括号或等于初始化程序中 (12.6.2),或
我们知道操作数未从节中求值5.2.8
其中说:
当 typeid 应用于除 a 的左值之外的表达式时
多态类类型,[...]表达式是未计算的操作数
(第 5 条)。
从语法中我们可以看出id-表达式是一个不合格的 ID or a 合格的 ID:
id-expression:
unqualified-id
qualified-id
Update
提交了海湾合作委员会错误报告:typeid 不允许使用表示非静态数据成员的 id 表达式 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68604.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)