c++ - 右值的成员访问运算符应该是 xvalue 吗?
问题描述
在cpprefernce 部分:值类别中,它声明“对象表达式的成员,其中 a 是右值,m 是非引用类型的非静态数据成员”是 xvalue。在标准中(我在:N4140,C++14 标准草案中找到)它声明(第 87 页)“如果表达式是 xvalue,则表达式是 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
}
如果我的计算是正确的,那么B().i
是“对象表达式的成员,其中 [ B()
] 是一个右值”,并且根据引用该表达式应该是一个 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 是一个 xvalue,那么 E1.E2 是一个 xvalue;否则,这是一个prvalue...
在 C++11之后更改为:
...如果 E1 是左值,则 E1.E2 是左值;否则 E1.E2 是一个 xvalue。...
推荐阅读
- python - Python While循环不执行else块
- java - 为什么在改造中需要 addConverterFactory
- javascript - 如何检查字符串中的单词对?
- wordpress - 'use fusion builder' 没有出现在 wordpress Avada 主题中
- java - 跳过库模块内的所有崩溃和异常
- python - 如何让这个猪拉丁代码发挥作用?
- c - 获取一个 char 和一个整数作为输入,或者只获取一个 char 作为输入
- java - 有没有办法浓缩这种比较多个结果的方法?
- scala - 链表中的协变类型 T
- python - Flask RestPlus Api 模块没有属性命名空间