“Временный объект”, предупреждающий - является этим меня или компилятор?

Следующий отрывок дает предупреждение:

[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...
7
задан Roddy 25 May 2010 в 14:12
поделиться

2 ответа

Простая попытка:

list1.push_back(new Derived());

Боюсь, что здесь что-то происходит между POD (с тривиальными конструкторами) и не-POD.

РЕДАКТИРОВАТЬ :

Учитывая, что код отлично компилируется с gcc.3.4.2 (--pedantic), я бы сказал, что это причуда компилятора. Я склоняюсь к объяснению MarkB , то есть компилятору, создающему временный объект, хотя я не понимаю, зачем он нужен, а затем жалуюсь при назначении его на const & ... но Я все еще в недоумении.

2
ответ дан 7 December 2019 в 12:15
поделиться

Поскольку 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(new Derived));

1
ответ дан 7 December 2019 в 12:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: