Следующий отрывок дает предупреждение:
[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!
Компилятор является Разработчиком C++ Codegear 2007.
Странно, если конструктор для Полученного удален, предупреждение уходит... Это - я или компилятор?
Править: Единственным путем я нашел для удаления предупреждения, к чему-то подобному этому:
Derived * d;
list1.push_back(d = new Derived); // << No warning now...
Простая попытка:
list1.push_back(new Derived());
Боюсь, что здесь что-то происходит между POD (с тривиальными конструкторами) и не-POD.
РЕДАКТИРОВАТЬ :
Учитывая, что код отлично компилируется с gcc.3.4.2 (--pedantic), я бы сказал, что это причуда компилятора. Я склоняюсь к объяснению MarkB
, то есть компилятору, создающему временный объект, хотя я не понимаю, зачем он нужен, а затем жалуюсь при назначении его на const &
... но Я все еще в недоумении.
Поскольку list1
является вектором Base*
, функция push_back
в списке будет ожидать параметр типа Base* const&
, в то время как ваш new предоставляет Derived*
. Для передачи по ссылке (как это требуется в push_back
) компилятору нужен реальный объект ссылочного типа, в данном случае Base*
. Существует доступное неявное преобразование из Derived*
в Base*
, которое компилятор использует для создания временного объекта типа Base*
для передачи в push_back
, и компилятор предупреждает вас, что он создает этот временный объект.
Причина, по которой он работает, когда вы присваиваете его переменной, в том, что больше нет необходимости в неявном временном: Он может неявно преобразовать именованную переменную в Base*
и передать эту ссылку внутрь.
Я думаю, вы можете заглушить это предупреждение, сказав push_back рассматривать указатель как Base*
:
list1. push_back(static_cast