【问题标题】:"Temporary object" warning - is it me or the compiler?“临时对象”警告 - 是我还是编译器?
【发布时间】:2011-02-23 17:23:51
【问题描述】:

下面的 sn-p 给出警告:

[C++ Warning] foo.cpp(70): W8030 Temporary used for parameter '_Val' in call to 'std::vector<Base *,std::allocator<Base *> >::push_back(Base * const &)'

.. 在指示的行上。

class Base
{
};

class Derived: public Base
{
public:
 Derived()   // << warning disappears if constructor is removed!
 {
 };
};

std::vector<Base*> list1;
list1.push_back(new Base);
list1.push_back(new Derived);  // << Warning on this line!

编译器是 Codegear C++Builder 2007。

奇怪的是,如果 Derived 的构造函数被删除,警告就会消失... 是我还是编译器?

编辑:我发现删除警告的唯一方法是类似于以下内容:

Derived * d;
list1.push_back(d = new Derived);  // << No warning now...

【问题讨论】:

  • 使用 gcc 对这段代码没有警告。
  • 这可能不是全部代码。 Base 和 Derived 是否有构造函数(非编译器生成的)?
  • @MadKeithV - 给予或接受#include ,即所有代码。我从一个更复杂的案例开始,并将其简化为显示上述问题的基本内容。
  • 您的问题出在编译器上。 BCC32有很多问题,我想这是另一个。

标签: c++ warnings c++builder


【解决方案1】:

简单的尝试:

list1.push_back(new Derived());

恐怕这里有一些关于 POD(带有微不足道的构造函数)与非 POD 的情况。

编辑

鉴于代码使用 gcc.3.4.2 (--pedantic) 编译得很好,我会说这是一个编译器怪癖。我倾向于MarkB 解释,即编译器创建一个临时的,即使我不明白为什么需要它,然后在将它分配给const&amp; 时抱怨......但我仍然感到困惑。

【讨论】:

  • 我没有方便的编译器来试验它,这很烦人:/ 没有为Base 生成相同的警告真的很奇怪:或者可能是因为Base 没有用户定义的构造函数?
  • Base 确实有一个用户定义的构造函数,但我把它删掉了,因为它对问题没有任何影响。即,使用“新基地”从未发出警告......
  • 这似乎是一个编译器错误。关于这个问题有一个开放的 QC 报告,“不正确的警告 W8030”。具有几乎相同的代码 sn-p。 qc.embarcadero.com/wc/qcmain.aspx?d=59272
【解决方案2】:

在“按引用传递”调用中,如果实参类型与“形参”不匹配,那么编译器将尝试将实参转换为正确的类型。如果转换成功,该参数将被视为“值参数”。在这种情况下,编译器会生成警告“Temporary used for ...”。

【讨论】:

  • 为我工作。 int 用于无符号参数。
【解决方案3】:

由于list1Base* 的向量,列表中的push_back 函数将需要Base* const&amp; 类型的参数,而您的新函数提供Derived*。为了通过引用传递(在push_back 中需要),编译器需要一个引用类型的实际对象,在本例中为Base*。有一个可用的从 Derived*Base* 的隐式转换,编译器使用它来创建 Base* 类型的临时对象以传递给 push_back,并且编译器警告您它正在​​创建这个临时对象。

将它分配给变量时它起作用的原因是不再需要隐式临时:它可以将命名变量隐式转换为 Base* 并隐式传递该引用。

我认为您可以通过告诉 push_back 将指针视为 Base* 来消除此警告:

list1.push_back(static_cast&lt;Base*&gt;(new Derived));

【讨论】:

  • 嗯。演员并没有改变事情,但我明白你在说什么。不过,我仍然不确定这两种隐式转换之间的区别。
  • 好的,那么为什么 Derived() 构造函数的存在很重要...?
  • 我想知道,但这对我来说没有意义。如果Derived* 可以隐式转换为Base*(就是这种情况),那么为什么Base*Derived* 会被区别对待?我认为不需要创建一个从Derived*Base* const&amp; 的临时对象(顺便检查一下您的答案中的const 位置),并且const&amp; 无论如何都可以绑定到临时对象......这让我很烦: /
猜你喜欢
  • 2015-02-09
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 2011-07-01
  • 2011-05-09
  • 2020-01-10
相关资源
最近更新 更多