【问题标题】:What is "a value not associated with an object"?什么是“与对象无关的值”?
【发布时间】:2014-09-04 20:54:29
【问题描述】:

C++11 和 C++14 标准(和工作草案,分别)在 §3.10.1 中说:

prvalue(“纯”右值)是一个不是 xvalue 的右值。 【示例:调用函数的结果 返回类型不是引用的就是prvalue。诸如 12、7.3e5 或 true 等文字的值是 也是prvalue。 ——结束示例]

一个右值(历史上所谓的,因为右值可能出现在赋值的右侧 expression) 是一个 xvalue、一个临时对象 (12.2) 或其子对象,或者 一个不相关的值 用一个对象

这让我想到了一个问题:表达式如何成为“不与对象关联的值”?

我的印象是,表达式的目的是返回对象或void(我也不希望它是一个值)。

这样的表达有一些简单而常见的例子吗?

编辑 1

要使事情变得更复杂,请考虑以下几点:

int const& x = 3;
int&& y = 4;

在 §8.3.2.5 的上下文中,其中包含最有趣的 sn-p:

[...] 一个引用应该被初始化为引用一个有效的对象或 功能 [...]

第 8.5.3.1 节加强了这一点:

声明为 T& 或 T&& 的变量,即“对类型 T 的引用”(8.3.2),应由对象初始化, 或函数,T 类型或可以转换为 T 的对象。[...]

【问题讨论】:

  • 42; ;;;;;;;;;;;;;;;;;
  • 非左值表达式产生,而不是对象。
  • @KeithThompson 那么,产生临时对象的纯右值表达式不会产生对象吗? 困惑
  • 我不完全确定;我比 C++ 更了解 C,而 C 只有左值和非左值。在任何情况下,表达式42 的值都是与对象无关的纯右值;评估 42 不会创建 int 对象。
  • 我立即认为nullptrtruethis 等可能是没有对象的值,但我不确定。

标签: c++ c++11 language-lawyer c++14


【解决方案1】:

[intro.object]:

C++ 程序中的构造创建、销毁、引用、访问和操作对象。对象是一个存储区域。 [注意:函数不是对象,无论它是否像对象那样占用存储空间。 —尾注] 对象由定义(3.1)、新表达式(5.3.4)或实现(12.2)在需要时创建。

因此,“与对象无关的值”不是通过定义或使用 new 表达式创建的,这也意味着它没有相应的存储区域,例如文字。

编辑:字符串文字除外(参见 cmets)

【讨论】:

  • 字符串字面量是左值(第 5.1.1.1 节)——这个定义是否意味着它们不是对象(与左值的定义冲突)并且没有相应的存储区域?
  • @gha.st:字符串文字是左值。我相信 Anton 指的是整数和浮点文字。
  • @MooingDuck 字符串文字不是由定义创建的,也不是由新表达式创建的,这让我怀疑它可能比满足(嗯,至少我的)更多眼睛
  • @gha.st 我认为这里的标准可能存在一些差距。如果字符串字面量是左值,它必须是一个对象,当然还有与之关联的存储区域,因为您可以将 const char* 指针分配给它。
  • @gha.st 3 不会导致创建对象,但引用投标会
【解决方案2】:

此类值的示例都是非数组、非类非临时纯右值(一个临时纯右值对应一个临时对象)。示例包括 2.01。反例包括"hello"(它是一个数组)、std::string("haha")(它是一个类对象)或从2 临时初始化的float prvalue,它绑定到(const float&){2} 中的引用(引用本身是一个左值!)。我认为这个简单的规则准确地涵盖了规则。

C++ 标准关于左值到右值转换的脚注说(有点过时,因为它没有被修改为提及数组类型)

在 C++ 中,类纯右值可以具有 cv 限定类型(因为它们是对象)。这与 ISO C 不同,其中非左值从不具有 cv 限定类型。

所以decltype((const int)0) 仍然int 类型的更深层原因是它不引用对象。所以因为没有对象,所以没有什么可以做 const,因此表达式也永远不会是 const。

【讨论】:

    【解决方案3】:

    这句话的措辞并不准确:

    右值(历史上称为右值,因为右值可能出现在赋值表达式的右侧)是一个 xvalue、一个临时对象 (12.2) 或其子对象,或者一个与对象无关的值.

    右值是一个表达式,所以它不能一个对象(临时的或其他的)。这句话中讨论临时对象的部分的意图是说从评估右值得到的值是一个临时对象,依此类推。

    这是一个常见的快捷方式,例如使用 int x; 我们会随便说 "x is in int" ,而实际上 x 是一个标识符;并且表达式 x 的类型为 int 并指定一个 int。

    无论如何,它将可能的右值分为三类:

    • xvalue
    • 临时对象
    • 值未与对象关联

    临时对象的定义包括作为类类型的对象,所以在我看来“与对象无关的值”应该是非类类型的任何非xvalue。例如1 + 1

    【讨论】:

    • “这意味着评估右值产生的值是一个临时对象” 我认为不一定是这种情况。整数文字是右值表达式,但没有与之关联的对象(即存储区域)。
    • @dyp 那么就不会是临时对象了,根据12.2的定义
    • 抱歉,我不太明白你所说的“then”和“it”是什么意思。
    • 在我的评论中? “那么”的意思是“作为你所说的结果”,而“它”的意思是你正在谈论的整数字面量。
    • @dyp 我认为我们意见一致。我的建议是,属于类类型的右值(不是 xvalues)是 临时对象,而不属于类类型的是 不与对象关联的值。跨度>
    猜你喜欢
    • 2015-09-03
    • 2011-10-27
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多