Скажем, у меня есть следующая иерархия классов:
struct Base
{
};
struct Derived : public Base
{
void DoStuffSpecificToDerivedClass()
{
}
};
И следующий метод factory:
std::unique_ptr<Base> factoryMethod()
{
auto derived = std::make_unique<Derived>();
derived->DoStuffSpecificToDerivedClass();
return derived; // does not compile
}
Проблема заключается в том, что оператор return
не компилируется, потому что std::unique_ptr
не имеет конструктора копирования с поддержкой ковариации (что имеет смысл, поскольку он не имеет каких-либо конструкторов), он имеет только конструктор перемещения с ковариационной поддержки.
Каков наилучший способ решить эту проблему? Я могу думать о двух путях:
return std::move(derived); // this compiles
return std::unique_ptr<Base>(derived.release()); // and this compiles too
EDIT 1: Я использую Visual С++ 2013 как мой компилятор. Исходное сообщение об ошибке для return derived
выглядит следующим образом:
Error 1 error C2664: 'std::unique_ptr<Base,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : cannot convert argument 1 from 'std::unique_ptr<Derived,std::default_delete<Derived>>' to 'std::unique_ptr<Derived,std::default_delete<Derived>> &&'
РЕДАКТИРОВАТЬ 2: Это только что созданное консольное приложение из стандартного шаблона VS 2013. Я не настраивал настройки компилятора. Командная строка компилятора выглядит так:
Debug:
/Yu"stdafx.h" /GS /analyze- /W3 /Zc:wchar_t /ZI /Gm /Od /sdl /Fd"Debug\vc120.pdb" /fp:precise /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_LIB" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\CppApplication1.pch"
Release:
/Yu"stdafx.h" /GS /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"Release\vc120.pdb" /fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_LIB" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\CppApplication1.pch"