【问题标题】:Qualified-ids, are they lvalues or prvalues?Qualified-ids,它们是左值还是纯右值?
【发布时间】:2014-10-13 18:20:54
【问题描述】:

我试图在 C++11 标准的第 5.1.1/8 段(第 87 页)中验证此声明(我的重点)

表示类的嵌套名称说明符,可选地后跟 关键字模板 (14.2),然后是成员的名称 属于该类(9.2)或其基类之一(第 10 条),是 一个合格的ID; 3.4.3.1 描述了类成员的名称查找 出现在qualified-ids中。结果是成员。的类型 结果是成员的类型。 如果 member 是静态成员函数或数据成员和纯右值 否则

使用以下 sn-p:

#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';
}

clanggcc编译这段代码,VS2013需要定义成员函数f

三个都打印

1
1

但我不知道这些数字是从哪里来的。

live example

根据上面突出显示的段落,表达式N::A::f 是prvalue,因为f 不是静态成员函数。尽管如此,我还是能够在代码中获取它的地址。

同时,在 §5.3.1/3 中写道(强调我的):

一元 & 运算符的结果是指向其操作数的指针。这 操作数应该是一个左值一个qualified-id。如果操作数是 qualified-id 命名某个类 C 的非静态成员 m,类型为 T, 结果的类型为“指向类型 T 的类 C 成员的指针”,并且是 prvalue 指定 C::m。

给人的印象是N::A::fN::A::i 都不是左值,因为它们是qualified-id

【问题讨论】:

  • 1 是指向成员的指针转换为bool
  • qualified-ids 都可以。在class C { static int x; }; 中,C::x 显然是一个左值。并且 5.3.1/3 中的 or 并不是唯一的。
  • 有一些qualified-ids肯定是prvalues:struct foo { enum bar { name = 0 }; };有这些定义,foo::name是prvalues。

标签: c++ c++11 language-lawyer lvalue qualified-name


【解决方案1】:

但我不知道这些数字是从哪里来的。

指向成员的指针不是指针。没有operator&lt;&lt; 可以输出它们的原始值,最好的也是唯一的匹配是输出bool 值的那个。因此它们被转换为bool(显然产生true)并且输出为1。尝试插入std::boolalpha 并再次检查输出。

尽管如此,我还是能够在代码中获取它的地址。

这对你有什么惊喜?你引用了允许并解释这个确切结构的部分。它明确指出,采用命名非静态成员的限定 ID 的地址指定该成员。

qualified-ids 不仅是左值或右值。这完全取决于上下文。如果他们从该成员类或其任何子类之外指定非静态成员,则它们必须是纯右值,因为它们不指定任何特定对象而是值(或信息,换句话说 - 类型和偏移量)。

【讨论】:

  • 只是出于好奇,为什么bool
  • @Aneri 为什么不呢?有一个到bool 的转换,没有转换到定义了任何operator&lt;&lt; 的任何其他类型。
  • "实际上,所有三个编译器都需要f 的定义。" -- 启用优化时,clang 和 gcc 都不会诊断缺少定义。
  • @hvd 是的,已启用优化。这无关紧要吗?无论如何,删除那部分,因为它真的无关紧要
  • @Loopunroller 它解释了为什么即使 OP 没有收到错误消息,您也可能会收到错误消息,我觉得这值得澄清。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
相关资源
最近更新 更多