c++ - typeid 不适用于非静态成员函数

标签 c++ c++11 language-lawyer typeid

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前两种情况不正确,但 gccsizeof 的情况下正常工作和 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/

相关文章:

c++ - 创建良好的目录结构

c++ - Bulls & Cows 项目 : cow checking

c++ - 光影在 opengl 和 c++ 中不起作用

类模板中的 C++ std::enable_if,用于成员函数

c++ - 为什么显式构造被视为(隐式)缩小转换?

c++ - 如何在 C++ 中编写一个接受可变数量的 char 数组参数的函数?

c++ - 如何为用户定义类型实现初始化列表? (类似于 std::vector 初始化列表)

c++ - 拥有 constexpr 静态字符串会导致链接器错误

c++ - 在普通对象安全的任何上下文中,原子对象是否不安全?

c++ - 为什么模板参数替换的顺序很重要?