开发者

"Temporary object" warning - is it me or the compiler?

The following snippet gives the warning:

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

.. on the indicated line.

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!

Compiler is Codegear C++Builder 2007.

Oddly, if the constructor for Derived is deleted, the warning goes away... Is it me or the compiler?

EDIT: The only way I've found to remove the warning is to something similar to this:

Derived * d;
开发者_StackOverflow社区list1.push_back(d = new Derived);  // << No warning now...


Simple try:

list1.push_back(new Derived());

I am afraid there is something about POD (with trivial constructors) vs non-POD going on here.

EDIT:

Given that the code compiles fine with gcc.3.4.2 (--pedantic) I would say it's a compiler quirk. I am leaning toward MarkB explanation, ie the compiler creating a temporary even though I don't understand why it would be required and then complaining when assigning it to the const&... but I'm still perplex.


In a "pass by reference" call, if the argument type does not match the "formal parameter", then the compiler will try to convert the argument to the correct type. The argument will be considered as a 'value parameter' if the conversion is successful. The compiler generates the warning "Temporary used for ..." in this case.


Since list1 is a vector of Base*, the push_back function in the list is going to expect a parameter of type Base* const&, while your new is providing Derived*. In order to pass by reference (as needed in push_back) the compiler needs an actual object of the reference type, in this case Base*. There is an available implicit conversion from Derived* to Base* that the compiler uses to create a temporary object of type Base* to pass into push_back, and the compiler is warning you that it's creating this temporary.

The reason it works when you assign it to a variable is that there's no longer an implicit temporary needed: It can implicitly convert the named variable to Base* implicitly and pass that reference in.

I think you can silence this warning by telling push_back to treat the pointer as a Base*:

list1.push_back(static_cast<Base*>(new Derived));

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜