理解左值到右值转换的例子
Understanding the example on lvalue-to-rvalue conversion
我很难理解此代码(来自 C++14 草案标准 [conv.lval] 的示例)如何为 [=11 调用未定义的行为=].为什么 constexpr
使程序有效?
另外,"does not access 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.n
3.2
中涵盖了 odr-use 的规则并说:
A variable x whose name appears as a potentially-evaluated expression ex is odr-used unless applying the
lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.19) that does not invoke any non-trivial
functions and, if x is an object, ex is an element of the set of potential results of an expression e, where
either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression
请注意,Ben Voigt 发表了一些有用的评论,稍微澄清了这一点。所以这里的工作假设是 x 将是:
y
和 e 将是(定义 e 的不同表达式包含在第 3.2 节的第 2 段中):
(b ? y : x).n
y
产生常量表达式,左值到右值的转换应用于表达式 e.
因为 f
产生一个 lambda,它通过引用捕获 f
的局部变量 x
一旦调用 f
就不再有效,因为 x
是f
里面的一个自动变量。由于 y
是一个 常量表达式 它的行为就好像 y.n
没有被访问,因此我们没有相同的生命周期问题。
您的示例包含在 N3939 部分 4.1
[conv.lval] 并且在该示例之前它说:
When an lvalue-to-rvalue conversion is applied to an expression e, and either
并包含考试所属的以下要点:
the evaluation of e results in the evaluation of a member ex of the set of potential results of e, and
ex names a variable x that is not odr-used by ex (3.2),
然后:
the value contained in the referenced object is not accessed
由于 defect report 1773,这已应用于 C++14 标准草案。
我很难理解此代码(来自 C++14 草案标准 [conv.lval] 的示例)如何为 [=11 调用未定义的行为=].为什么 constexpr
使程序有效?
另外,"does not access 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.n
3.2
中涵盖了 odr-use 的规则并说:
A variable x whose name appears as a potentially-evaluated expression ex is odr-used unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.19) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression
请注意,Ben Voigt 发表了一些有用的评论,稍微澄清了这一点。所以这里的工作假设是 x 将是:
y
和 e 将是(定义 e 的不同表达式包含在第 3.2 节的第 2 段中):
(b ? y : x).n
y
产生常量表达式,左值到右值的转换应用于表达式 e.
因为 f
产生一个 lambda,它通过引用捕获 f
的局部变量 x
一旦调用 f
就不再有效,因为 x
是f
里面的一个自动变量。由于 y
是一个 常量表达式 它的行为就好像 y.n
没有被访问,因此我们没有相同的生命周期问题。
您的示例包含在 N3939 部分 4.1
[conv.lval] 并且在该示例之前它说:
When an lvalue-to-rvalue conversion is applied to an expression e, and either
并包含考试所属的以下要点:
the evaluation of e results in the evaluation of a member ex of the set of potential results of e, and ex names a variable x that is not odr-used by ex (3.2),
然后:
the value contained in the referenced object is not accessed
由于 defect report 1773,这已应用于 C++14 标准草案。