警告:不应该用临时类型初始化非const引用

Warning: should not initialize a non-const reference with a temporary

本文关键字:初始化 const 引用 类型 不应该 警告      更新时间:2023-10-16

我用下面的代码片段从Sun Studio 12.1的标题中得到警告:

#include <vector>
std::vector<int> g()
{
  std::vector<int> result;
  result.push_back(5);
  return result;
}
int main()
{
  int b = g()[0];  // <- Warning in this line
  return b;
}

警告文本为:

Warning: should not initialize a non-const reference with a temporary.

虽然我知道用临时对象初始化非const引用是一件坏事,但我不明白这里是怎么发生的。我知道[0]返回对向量的第一个元素的引用,该元素本身是临时的,但我看不出问题是什么。

谁能解释一下

    为什么编译器会报错?
  • 是一个合法的警告吗?
    • 如果是,我需要改变什么?
    • 如果没有,我怎样才能优雅地静音它?

不,这是不合法的。g()的返回值是临时的,但它不是const -您只是无法获得对它的非const引用。在这里调用非const成员operator[]是完全有效的,从双精度到整型的转换也同样安全。

这个Sun编译器看起来很奇怪,对我来说根本不合法。Ideone编译它没有问题

关于静音部分:

std::vector<double> const tmp = g();
int b = tmp[0];

也就是说,引入一个命名变量,而不是留下临时的浮动变量。

编辑:

如注释中所建议的,对返回值进行const限定可能会有所帮助。

std::vector<double> const g();
int main() {
  int b = g()[0];
  return b;
}

是的,它确实用临时变量初始化了非const引用。但只是在重载解析期间的概念上,而不是实际上。编译器不应该对此发出警告。

在过载解析中,operator[]具有以下函数参数签名

operator[](std::vector<int>&, std::vector<int>::size_type);

第一个形参将接收g()返回的临时形参,但如上所述,这很好,c++为该引用专门创建了一个异常,即所谓的"隐式对象形参",以便重载解析接受临时形参。