c++ - 通过指针转换将右值绑定(bind)到非常量引用?

标签 c++ reference g++ rvalue

我不明白下面的代码是如何编译/不编译的:

struct Temp
{
  int i;
};

int main(int argc, char * argv[])
{
   //Temp &ref1 = (Temp){42}; // Error, as expected
   Temp &ref2 = *(Temp*)&(Temp){42}; // A-OK
   std::cerr << ref2.i << std::endl;
   return 0;
}

我正在使用 g++ 4.4.4。

最佳答案

您的代码不是真正的 C++。它使用复合文字,这是 C99 的一个特性。在 C99 中,它计算为一个左值,并且获取文字的地址在那里完全没问题。将此扩展集成到 C++ 中,GCC 似乎改变了它的规则并使其成为右值,从而更好地将它们的分类纳入 C++ 的现有规则中,以用于也产生右值的常规转换。

GCC 不喜欢 &(Temp){42},提示我拿了临时地址。这是一个关于无效代码的警告,它仍然接受但并不真正喜欢。对于其他明显错误的代码,如 &A() 也会给出相同的警告,这是一种合法的函数式 C++ 转换,它也会产生一个右值,因此不能用作地址的操作数运算符(operator)。

GCC 将复合文字集成到 C++ 中也过早地破坏了临时变量,如下面的测试可以看出

#include <iostream>
struct B {
  ~B() {
    std::cout << "~B" << std::endl;
  }
};
struct A { int i; B b; };

int main() {
  A *a = &(A){0};
  std::cout << "main" << std::endl;
}

在 C99 中,字面量所指的对象在整个 block 中都是有效的(它将具有自动存储持续时间)。在 GNU C++ 中,对象已经在完整表达式的末尾被破坏,甚至在到达其 block 末尾之前(“~B”打印在“main”之前)。

关于c++ - 通过指针转换将右值绑定(bind)到非常量引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5061275/

相关文章:

c++ - CMake-附件.h : No such file or directory

c# - 检查.NET 3.5中对给定实例保留了多少引用

ios - “strcmp”未在此范围内声明

c++ - 一个简单的 C++ While 循环不起作用

c++ - 如何在处理过程中更新 OpenGL 中的显示?

c++ - 通过引用传递是作为指针传递的特例吗?

C++ 如何将一个函数的引用传递给另一个函数?

C++ 编译错误 : ‘pair’ does not name a type

c++ - usr/bin/ld : cannot find -l<nameOfTheLibrary>

c# - C# 中不保留 C++ 函数中的数组更改