了解左值到右值转换的示例

2024-05-04

我很难理解这段代码(来自 C++14 草案标准的示例)[转换拉瓦尔]) 调用未定义的行为g(false)。为什么constexpr使程序有效?

另外,“不访问”是什么意思?y.n“?在两次通话中g()我们正在返回n数据成员那么为什么最后一行说它不能访问它呢?

struct S { int n; };
auto f() {
    S x { 1 };
    constexpr S y { 2 };
    return [&](bool b) { return (b ? y : x).n; };
}
auto g = f();
int m = g(false); // undefined behavior due to access of x.n outside its
                  // lifetime
int n = g(true);  // OK, does not access y.n

这是因为y.n不使用 ODR,因此不需要访问y.nODR 使用规则包含在3.2并说:

名称显示为潜在计算表达式 ex 的变量 x已使用 odr,除非应用 左值到右值转换 (4.1) 到 x产生一个常量表达式(5.19) 不调用任何非平凡的 函数,如果 x 是对象,则 ex 是表达式 e 的潜在结果集合的元素,其中左值到右值的转换 (4.1) 应用于 e,或 e 是丢弃值表达式

请注意,Ben Voigt 发表了一些有用的评论,稍微澄清了这一点。所以这里的工作假设是x将会:

y

and e将会(e 定义的不同表达式包含在第 3.2 节第 2 段中):

(b ? y : x).n

y产生一个常量表达式,并将左值到右值的转换应用于该表达式e.

Since f产生一个 lambda 捕获f通过引用的局部变量x一旦调用就不再有效f自从完成x里面是一个自动变量f. Since y is a 常量表达式它的行为就好像y.n没有被访问,因此我们没有相同的生命周期问题。

您的示例包含在N3939 https://github.com/cplusplus/draft/blob/b7b8ed08ba4c111ad03e13e8524a1b746cb74ec6/papers/N3936.pdf部分4.1 [转换拉瓦尔]在这个例子之前它说:

当左值到右值转换应用于表达式 e 时,并且

并包括该示例所属的以下项目符号:

对 e 的评估导致对 e 的潜在结果集中的成员 ex 进行评估,并且 ex 命名一个变量 x未使用 ODR由前 (3.2) 得出,

then:

the 未访问引用对象中包含的值

这被应用于 C++14 草案标准,因为缺陷报告 1773 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3953.html#1773 .

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解左值到右值转换的示例 的相关文章

随机推荐