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?