c++ - 临时对象的字段是右值吗?

标签 c++

此代码在 Clang 3.8、GCC 6.3 和 VS2013 下编译成功,但在 Clang 4.0 下编译失败:

struct Foo {
  int x[2];
  Foo() {
    x[0] = 3; // line A: works fine - we can assign to x[0]
    *&x[0] = 4; // line B: works fine - we can take the address of x[0]
  }
};

int main() {
  Foo().x[0] = 5; // line C: error: expression is not assignable
  *(Foo().x + 0) = 6; // line D: works fine
}

哪个编译器是正确的? Foo().x[0] 是右值还是左值?

A 行和 B 行适用于所有编译器,x[0] 绝对是那里的左值,A 行和 B 行肯定引用相同的 x 作为C 行,所以看起来 Foo().x[0] 应该是一个左值。但是,当以这种方式访问​​时,Foo() 的右值性可能会传播到它的所有字段吗?

还要考虑适用于所有编译器的 D 行。我认为 bar[n] 基本上只是 *(bar + n) (对于数组)的语法糖,所以 D 行工作但 C 行失败似乎很奇怪.

最佳答案

Foo().x[0] 在 C++11 中是左值。在 C++11 中,内置下标运算符的结果始终是左值,因为它涉及取消引用指针。

在 C++14 中,内置下标运算符的行为发生了变化:

  • 如果 a 是左值,则 a[i] 也是左值。
  • 否则,a[i] 是一个 xvalue。

Foo() 是纯右值,因此访问非静态成员会产生缺值。因为 Foo.x 是一个 xvalue,Foo.x[0] 也是一个 xvalue,不能赋值给它。

关于c++ - 临时对象的字段是右值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44447031/

相关文章:

c++ - 使用 lambda 完美转发pair.second

c++ - 如何避免远距离的Z-fighting?

c++ - 结构新手,我对如何从 void 函数返回值并将其放入另一个函数感到困惑

c++ - 如何找到两个不同数组中交换的值?

c++ - C++ 中的 SQLite3 多线程 (linux)

c++ - 如何使用模板别名删除一个不必要的参数

c++ - 运行 cmake 后出现 undefined reference 错误

c++ - Eclipse 内容辅助无法识别 std::thread,但可以正确编译

c++ - vector 调整大小与嵌套 vector 的保留

c++ - 调节 SDL Sprite 速度 C++