右值的成员访问运算符应为xvalue吗?

时间:2018-11-05 19:22:19

标签: c++ decltype rvalue lvalue xvalue

cpprefernce section: Value categories中,它声明“对象表达式的成员,其中a为右值,m为非引用类型的非静态数据成员”为xvalue。在标准(我在N4140, the draft C++14 standard中找到),它指出(在第87页上)“如果表达式是x值,则它是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()]是一个右值”,根据引用,该表达式应为x值,并且decltype返回的类型应为int &&。请注意,我正在使用gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04),并且在没有标志的情况下使用-std=c++14进行了尝试。

(为清楚起见,我也在这里检查我对“ decltype”的理解,但是我之前链接的标准和参考文献完全逐字记录,非常清楚地体现了decltype的行为。)

对不起,这不是问题,对吗?应该更新参考文献以澄清这种行为吗?

1 个答案:

答案 0 :(得分:1)

是的,您是对的,这是一个错误,看起来与Is f().a[0] an xvalue?类似,但是此案例专门处理了在[expr.sub]p1中有分界的数组,该数组表示结果是左值,但是{{ 3}}。否则,将应用相同的逻辑。

我们可以看到它是deemed a defect,如果我们检查fixed in clang 4.0,我们将获得与clang < 4.0 live相同的不合格结果,但是gcc less than the most HEAD也是固定的。

还要注意,clang 4.0 and > live中的问题也仅在Is f().a[0] an xvalue?中得到解决。

还要注意gcc HEAD

  

...如果E1是一个左值,那么E1.E2是一个左值;如果E1是一个xvalue,则E1.E2是一个xvalue;否则,它是一个prvalue ...

在C ++ 11之后更改为[expr.ref]p4.2

  

...如果E1是一个左值,那么E1.E2是一个左值;否则E1.E2是一个xvalue。 ...

虽然不确定与this的关系,但看起来原本是DR 616的一部分。