Nat*_*ell 5 c++ rvalue decltype lvalue xvalue
在cpprefernce部分:值类别中,它声明"对象表达式的成员,其中a是rvalue,m是非引用类型的非静态数据成员"是xvalue.在标准(我发现于:N4140,草案C++ 14标准)中,它声明(在第87页)"如果表达式是......一个指定非静态数据成员的类成员访问表达式,则表达式是xvalue对象表达式为xvalue的非引用类型."
我想通过以下代码检查我对此的理解:
struct B { // B for Boring...
int i{0};
};
template <typename T> struct V {
V() { cout << "V" << endl; }
};
template <typename T> struct V<T &> { // Partial Specialization
V() { cout << "V&" << endl; }
};
template <typename T> struct V<T &&> { // Partial Specialization
V() { cout << "V&&" << endl; }
};
int main() {
int i{1};
V<decltype((1))> v1; // V
V<decltype((i))> v2; // V&
V<decltype((move(i)))> v3; // V&&
V<decltype((B().i))> v4; // V, why not V&&?
V<decltype((move(B()).i))> v5; // V&& as expected
}
Run Code Online (Sandbox Code Playgroud)
如果我的计算是正确的,那么B().i它是"对象表达式的成员,其中[ B()]是一个rvalue,"并且根据引用,表达式应该是一个xvalue,返回的类型decltype应该是int &&.请注意,我正在使用gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04),我尝试了没有标志和-std=c++14.
(为了清楚起见,我也在这里检查我对"decltype"的理解,但我之前链接的标准和参考文献逐字同意并且非常明确地说明了decltype的行为).
对不起,那不是问题......我是对的吗?是否应更新引用以澄清此行为?
是的,你是对的,这是一个错误,这看起来类似于Is f().a[0]an xvalue? 但本例专门处理在[expr.sub]p1中进行了雕刻的数组,该数组表示结果是左值,但被视为缺陷。否则同样的逻辑适用。
我们可以看到它在 clang 4.0 中已修复,如果我们检查clang < 4.0 live,我们会得到与您从 gcc 看到的相同的不合格结果,小于大多数 HEAD但clang 4.0 和 > live这也已修复。
另请注意Is f().a[0]an xvalue?中的问题。也仅在gcc HEAD中修复。
另请注意[expr.ref]p4.2
...如果 E1 是左值,则 E1.E2 是左值;如果 E1 是 x 值,则 E1.E2 是 x 值;否则,它是一个纯右值...
C++11 之后更改为:
...如果 E1 是左值,则 E1.E2 是左值;否则 E1.E2 是 x 值。...
看起来这个变化最初是DR 616的一部分,尽管我不确定它与不确定值有什么关系。