右值的成员访问运算符应该是一个 xvalue 吗?
Should the member access operator of an rvalue be an xvalue?
在 cpprefernce section: Value categories, it states that "the member of object expression, where a is an rvalue and m is a non-static data member of non-reference type" is an xvalue. In the standard (I found in: N4140, the draft C++14 standard) 中指出(第 87 页)"An expression is an xvalue if it is... a class member access expression designating a non-static data member of non-reference type in which the object expression is an 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
}
如果我的计算是正确的,那么 B().i
是一个 "member of object expression, where [B()
] is an rvalue," 并且根据引用,表达式应该是一个 xvalue,而 decltype
返回的类型应该是 int&&。请注意,我使用的是 gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
,我在没有标志和 -std=c++14
.
的情况下进行了尝试
(明确地说,我也在此处检查我对 "decltype" 的理解,但我之前链接到的标准和参考资料在 decltype 的行为上逐字一致且非常清楚)。
抱歉,这不是问题...我说得对吗?是否应更新参考以澄清此行为?
是的,你是对的,这是一个错误,这看起来类似于 but this case dealt speifically with arrays which had a carve out in [expr.sub]p1 which said the result was an lvalue but deemed a defect。否则同样的逻辑适用。
我们可以看到它是fixed in clang 4.0 and if we check clang < 4.0 live, we obtain the same non-conforming results you see from gcc less than the most HEAD but clang 4.0 and > live这也是固定的。
另请注意 is also only fixed in gcc HEAD 中的问题。
另请注意 [expr.ref]p4.2
... If E1 is an lvalue, then E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue; otherwise, it is a prvalue...
在 C++11 之后更改为 this:
... If E1 is an lvalue, then E1.E2 is an lvalue; otherwise E1.E2 is an xvalue. ...
看起来更改最初是 DR 616 although what it has to do with indeterminate values 的一部分,我不确定。
在 cpprefernce section: Value categories, it states that "the member of object expression, where a is an rvalue and m is a non-static data member of non-reference type" is an xvalue. In the standard (I found in: N4140, the draft C++14 standard) 中指出(第 87 页)"An expression is an xvalue if it is... a class member access expression designating a non-static data member of non-reference type in which the object expression is an 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
}
如果我的计算是正确的,那么 B().i
是一个 "member of object expression, where [B()
] is an rvalue," 并且根据引用,表达式应该是一个 xvalue,而 decltype
返回的类型应该是 int&&。请注意,我使用的是 gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
,我在没有标志和 -std=c++14
.
(明确地说,我也在此处检查我对 "decltype" 的理解,但我之前链接到的标准和参考资料在 decltype 的行为上逐字一致且非常清楚)。
抱歉,这不是问题...我说得对吗?是否应更新参考以澄清此行为?
是的,你是对的,这是一个错误,这看起来类似于
我们可以看到它是fixed in clang 4.0 and if we check clang < 4.0 live, we obtain the same non-conforming results you see from gcc less than the most HEAD but clang 4.0 and > live这也是固定的。
另请注意
另请注意 [expr.ref]p4.2
... If E1 is an lvalue, then E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue; otherwise, it is a prvalue...
在 C++11 之后更改为 this:
... If E1 is an lvalue, then E1.E2 is an lvalue; otherwise E1.E2 is an xvalue. ...
看起来更改最初是 DR 616 although what it has to do with indeterminate values 的一部分,我不确定。