clang
不会编译下面对 typeid
的第三次调用(请参阅 live example )。但是我在 §5.2.8 中看不到任何不允许这样做的内容,特别是当我们认为表达式 B::f
不是多态类类型的泛左值时(参见第 3 段)。此外,根据本段,表达式 B::f
是未计算的操作数,因此,调用 typeid(B::f)
应该编译。请注意,GCC
不会编译以下对 typeid
的任何调用:
#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
的情况下正常工作和 decltype
也有未计算的操作数。
来自 draft C++11 standard栏目5.1.1
[expr.prim.general]:
An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
并包括以下项目符号:
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
—end example ]
其余项目符号不适用,如下:
- 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
部分未计算操作数其中说:
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:
id-expression:
unqualified-id
qualified-id
更新
提交了 gcc bug report: typeid does not allow an id-expression that denotes a non-static data member .
关于c++ - typeid 不适用于非静态成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28053640/