c++ - 右值的成员访问运算符应该是一个 xvalue 吗?

标签 c++ decltype rvalue lvalue xvalue

cpprefernce section: Value categories ,它指出“对象表达式的成员,其中 a 是右值,m 是非引用类型的非静态数据成员”是一个 xvalue。在标准中(我在:N4140, the draft C++14 standard 中找到)它声明(在第 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
}

如果我的计算是正确的,那么 B().i是“对象表达式的成员,其中 [ B() ] 是一个右值”,根据引用,该表达式应该是一个 xvalue,以及 decltype 返回的类型应该是整数&&。请注意,我使用的是 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 中划分的数组它表示结果是一个左值但是 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 .

另请注意 [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 的一部分虽然它与indeterminate values有什么关系我不确定。

关于c++ - 右值的成员访问运算符应该是一个 xvalue 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53160833/

相关文章:

c++ - 传递 CString 和传递 CString.GetBuffer 到 CString.Format 中的 %s 之间有什么区别吗

c++ - `decltype(&ordenary_func)`和decltype`(ordenary_func)之间的区别

c++ - 从右值对象返回一个成员

c++ - vector::push_back 和 std::move

perl - Perl 中有哪些语法糖可以减少 l/rvalue 运算符与 if 语句的代码?

c++ - 不同来源的QT调用函数

c++ - 使用 cmake 将依赖项传播到仅 header 的 ExternalProject

c++ - 如何使我的工厂的标题不依赖于它创建的模板化对象?

c++ - 使用 auto 和 decltype 从模板类中的函数返回引用

c++ - 完美转发