我试图在C ++ 11标准的第5.1.1 / 8页(第87页)中验证这一陈述(我的重点)
表示类的嵌套名称说明符,可选地后跟 关键字模板(14.2),然后是成员的名称 该类(9.2)或其基类之一(第10条)是 合格的身份; 3.4.3.1描述了类成员的名称查找 出现在qualified-id中。结果是成员。的类型 结果是成员的类型。 如果是,结果是左值 member是静态成员函数或数据成员和prvalue 否则
使用以下代码段:
#include <iostream>
namespace N {
class A {
public:
int i;
void f();
};
}
int main()
{
std::cout << &N::A::f << '\n';
std::cout << &N::A::i << '\n';
}
clang
和gcc
编译此代码,VS2013
需要成员函数f
的定义。
所有三个都打印
1
1
但我不知道这些数字来自哪里。
根据上面突出显示的段落,表达式N::A::f
是prvalue,因为f
不是静态成员函数。尽管如此,我还是能够在代码中获取其地址。
同时,在§5.3.1/ 3中,一个读(强调我的):
一元&amp;的结果operator是指向其操作数的指针。该 操作数应为左值或 qualified-id 。如果操作数是a qualified-id 命名某个类C的非静态成员m,类型为T, 结果有类型“指向T类C类成员的指针”,是一个 prvalue指定C :: m。
给人的印象是N::A::f
和N::A::i
都不是左值,因为它们是 qualified-id 。
答案 0 :(得分:2)
但我不知道这些数字来自哪里。
指向成员的指针不是指针。没有operator<<
可以输出其原始值,最佳且仅匹配是输出bool
值的匹配。因此,它们将转换为bool
(显然会产生true
),输出为1
。尝试插入std::boolalpha
并再次检查输出。
尽管如此,我能够在代码中获取其地址。
这对你来说有多大惊喜?您引用了允许并解释此确切构造的部分。它明确指出,取名为非静态成员的限定id的地址指定该成员。
qualified-id 不仅是左值还是左值。它完全取决于背景。如果他们从成员类或其任何子类外部指定非静态成员,则它们必须是prvalues,因为它们不指定任何特定对象而是指定值(或信息,换句话说 - 类型和偏移量)。