C++ typeid不';不能使用非静态成员函数

C++ typeid不';不能使用非静态成员函数,c++,c++11,language-lawyer,typeid,C++,C++11,Language Lawyer,Typeid,clang不会编译下面对typeid的第三个调用(请参阅)。但是在5.2.8中我看不到任何不允许这样的东西,特别是当我们认为表达式::f>代码>不是多态类类型的GLUT(见第3段)。此外,根据本段,表达式B::f是未赋值的操作数,因此,调用typeid(B::f)应该编译。请注意,GCC不会编译下面对typeid的任何调用: #include <iostream> #include <typeinfo> struct A{ int i; }; struct B{ int

clang
不会编译下面对
typeid
的第三个调用(请参阅)。但是在5.2.8中我看不到任何不允许这样的东西,特别是当我们认为表达式<代码>::f>代码>不是多态类类型的GLUT(见第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';
}
#包括
#包括
结构A{int i;};
结构B{int i;void f();};
int main()
{

std::cout据我所知,
clang
是正确的,使用非静态成员仅在未计算的上下文中(如果它是数据成员)才有效。因此看起来
gcc
在前两种情况下是不正确的,但是
gcc
sizeof
decltype
也有unevalua的情况下工作正常ted操作数

从章节
5.1.1
[expr.prim.general]:

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

并包括以下项目符号:

如果该id表达式表示非静态数据成员,则 在未计算的操作数中。[示例:

-[结束示例]

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

  • 作为类成员访问(5.2.5)的一部分,其中对象表达式引用成员的类61或从该类派生的类 类,或
  • 形成指向构件(5.3.1)的指针,或
  • 在该类或从该类派生的类(12.6.2)的构造函数的mem初始值设定项中,或
  • 在该类或从该类派生的类(12.6.2)的非静态数据成员的大括号或等效初始值设定项中,或
我们从
5.2.8节
中知道操作数是未计算的,该节说:

当typeid应用于表达式而不是 多态类类型,[…]表达式是未赋值的操作数 (第5条)

我们可以从语法中看出,id表达式是非限定id或限定id:

更新

提交了一个gcc。

typeid(a::i).name()
并没有达到我想象的效果。我希望它是一个指向成员的指针,但实际上它只是一个
int

要查看此信息,请运行以下代码:

#include <iostream>
struct A{ int i; };
struct B{ int i; void f(void); };

template<typename T>
void what_is_my_type() {
    std:: cout << __PRETTY_FUNCTION__ << std:: endl;
}

int main()
{
    what_is_my_type<decltype(&A::i)>(); // "void what_is_my_type() [T = int A::*]"
    what_is_my_type<decltype(&B::i)>(); // "void what_is_my_type() [T = int B::*]"
    what_is_my_type<decltype(&B::f)>(); // "void what_is_my_type() [T = void (B::*)()]"

    what_is_my_type<decltype(A::i)>();  // "void what_is_my_type() [T = int]"
    what_is_my_type<decltype(B::i)>();  // "void what_is_my_type() [T = int]"
    // what_is_my_type<decltype(B::f)>();       //    doesn't compile

}
但这样做是不可能的(甚至是没有意义的):

B b;
???   y = &(a.f); // what does this even mean?
<>最后,强调这不是关于指针,考虑这个:

A a;
B b;
int x = a.i;
int y = b.i;
??? z = b.f;  // what would this mean? What's its type?

@Yakk我用g++进行了测试,确认这三个编译器都没有编译,然后编辑了问题以修复双重否定。将
&
放入其中会使这两个编译器都能工作,例如
&B::I
。但是,我想这不是重点!为什么它们在没有
&
的情况下不能工作?@MarkB感谢你的更正。正如你所说的那样an see我不能完全掌握英语。我已重命名了问题标题。请随意再更改一次!原来的问题标题完全没有用处:-)为此提交了一份错误报告。Darn--几乎完成了一个完全相同的答案,但正在从中格式化
主表达式的语法5.1.1当您发布。。。
A a;
int * x = &(a.i);
*x = 32;
B b;
???   y = &(a.f); // what does this even mean?
A a;
B b;
int x = a.i;
int y = b.i;
??? z = b.f;  // what would this mean? What's its type?