C++ 理解左值到右值转换示例
我很难理解这段代码(来自C++14标准草案[conv.lval]的示例)如何调用C++ 理解左值到右值转换示例,c++,language-lawyer,c++14,constexpr,lvalue-to-rvalue,C++,Language Lawyer,C++14,Constexpr,Lvalue To Rvalue,我很难理解这段代码(来自C++14标准草案[conv.lval]的示例)如何调用g(false)的未定义行为。为什么constexpr使程序有效 另外,“不访问y.n”是什么意思?在对g()的两个调用中,我们都返回n数据成员,那么为什么最后一行说它不访问它呢 结构{int n;}; 自动f(){ sx{1}; constexpr S y{2}; return[&](boolb){return(b?y:x).n;}; } 自动g=f(); int m=g(假);//由于x.n在其外部访问而导致的未
g(false)
的未定义行为。为什么constexpr
使程序有效
另外,“不访问y.n
”是什么意思?在对g()
的两个调用中,我们都返回n
数据成员,那么为什么最后一行说它不访问它呢
结构{int n;};
自动f(){
sx{1};
constexpr S y{2};
return[&](boolb){return(b?y:x).n;};
}
自动g=f();
int m=g(假);//由于x.n在其外部访问而导致的未定义行为
//一生
int n=g(真);//好的,不访问y.n
这是因为
y.n
未使用odr,因此不需要访问y.n
odr的使用规则在3.2
中介绍,并说明:
除非应用
从左值到右值的转换(4.1)到x产生一个不调用任何非平凡函数的常量表达式(5.19)
函数,如果x是对象,则ex是表达式e的潜在结果集的元素,其中
左值到右值的转换(4.1)应用于e,或者e是一个废弃的值表达式
注意,Ben Voigt发表了一些有用的评论,澄清了这一点。因此,这里的工作假设是x为:
y
而e将是(第3.2节第2段涵盖了定义e的不同表达式):
y
生成一个常量表达式,并将左值到右值的转换应用于表达式e
由于f
生成一个lambda,该lambda通过引用捕获f
的局部变量x
一旦调用f
就不再有效,因为x
是f
中的一个自动变量。由于y
是一个常量表达式,它的行为就好像没有访问y.n
,因此我们没有相同的生存期问题
您的示例包含在章节4.1
[conv.lval]中,在该示例之前,它说:
将左值到右值的转换应用于表达式e时
并包括examle所属的以下项目符号:
e的评估结果是对e的潜在结果集的成员ex的评估,以及
ex命名了一个变量x,该变量x不是ex(3.2)使用的odr
然后:
未访问引用对象中包含的值
这适用于C++14标准草案,原因是。我猜
constexpr
在编译时进行计算,并存储在程序的某个只读部分,与堆栈帧无关,而x
在堆栈帧中,在堆栈帧被删除后访问它会导致未定义的行为。您在哪里找到这个示例?在标准中,还是其他来源?@BenVoigt它来自C++14[conv.lval]/2.2.@BenVoigt您的评论非常有用。实际上,我刚刚开始深入研究ODR规则,因为最近w.r.t向constexpr和ODR提出了一些与我有关的问题。相对较新的措辞并不直截了当,仅有的一些解释也不是很好。@ShafikYaghmour:是的,我真的不喜欢“表达式的潜在结果”这个术语,它与同一表达式的“结果”完全无关。什么叫“引用对象中包含的值未被访问”? 2
是y.n
的值,这是否意味着我不从g(true)
返回2
?您确实从g(true)
返回2,但程序不必访问名为y.n
的物理内存位置来获取该值。
(b ? y : x).n