[英]Understanding the example on lvalue-to-rvalue conversion
我很难理解这段代码(C ++ 14草案标准[conv.lval]中的一个例子)如何调用g(false)
未定义行为。 为什么constexpr
使程序有效?
另外,“不访问yn
”是什么意思? 在对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
这是因为yn
不ODR使用的,因此不需要访问yn
为ODR使用覆盖在规则3.2
,并说:
变量x的名称显示为潜在评估的表达式ex, 除非将lvalue-to-rvalue转换(4.1)应用于x, 否则将生成一个不调用任何非平凡函数的常量表达式 (5.19),并且如果x是一个对象,ex是表达式e的潜在结果集合的元素,其中左值到右值的转换(4.1)应用于e ,或者e是丢弃值表达式
请注意,Ben Voigt做了一些有用的评论,澄清了这一点。 所以这里的工作假设是x将是:
y
e将是( 第3.2节第2段所述的e定义的不同表达式 ):
(b ? y : x).n
y
产生一个常量表达式,并将左值到右值转换应用于表达式e 。
因为f
产生一个lambda,它通过引用x
捕获f
的局部变量,一旦完成对f
的调用就不再有效,因为x
是f
内的自动变量。 由于y
是一个常量表达式,因此它就像没有访问yn
,因此我们没有相同的生命周期问题。
您的示例包含在N3939第4.1
节[conv.lval]中 ,就在该示例之前,它说:
将左值到右值转换应用于表达式e和其中之一
并包括考试所属的以下子弹:
对e的评估结果是对e的潜在结果集合的成员ex的评估,并且ex为变量x命名,该变量x 不是由ex(3.2)使用的,
然后:
不访问引用对象中包含的值
由于缺陷报告1773,这适用于C ++ 14草案标准。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.