Я думаю, сокращенная версия:
struct X
{
X() {}
X(X&);
};
X make() { return X(); }
void receive(X ) { }
int main()
{
receive(make());
}
Обратите внимание на необычную форму конструктора копирования (из неконстантной ссылки), которая предотвращает (по стандарту, GCC верна) возможность копирования-конструирования экземпляра из временного (результат make()
).
Ситуация намного сложнее, потому что std::auto_ptr
пытается обойти полученные ограничения с помощью оболочки auto_ptr_ref
. Однако, поскольку вы также хотите изменить тип указателя, он, вероятно, где-то ломается со всеми этими неявными преобразованиями, и VC ++ удается его скомпилировать только благодаря нестандартному расширению (позволяющему связывать значения с непостоянными ссылками).
Компилятор действительно говорит мне это правильно. На проблемной линии:
warning C4239: nonstandard extension used : 'argument' :
conversion from 'std::auto_ptr<_Ty>' to 'std::auto_ptr<_Ty> &'
В любом случае, std::auto_ptr
- это неудачный эксперимент с причудливой семантикой, и в следующем стандарте он устарел. В C ++ 0x (например, с gcc 4.4.1) это сработало бы, если бы вы заменили все вхождения auto_ptr
на unique_ptr
и изменили сигнатуру функций приемника, чтобы использовать ссылки rvalue для получения передачи владения.
void sink_base( std::unique_ptr<Base>&& p);