Powiedzmy mam następującą hierarchię klas:Prawidłowy sposób powrocie std :: unique_ptr do obiektu polimorficznych klasy
struct Base
{
};
struct Derived : public Base
{
void DoStuffSpecificToDerivedClass()
{
}
};
oraz następujące metody fabryki:
std::unique_ptr<Base> factoryMethod()
{
auto derived = std::make_unique<Derived>();
derived->DoStuffSpecificToDerivedClass();
return derived; // does not compile
}
Problem jest, instrukcja return
nie kompiluje się, ponieważ std::unique_ptr
nie ma konstruktora kopii z obsługą kowariancji (co ma sens, ponieważ nie ma żadnych konstruktorów kopiowania), ma tylko konstruktor ruchu z obsługą kowariancji.
Jaki jest najlepszy sposób rozwiązania tego problemu? Myślę można na dwa sposoby:
return std::move(derived); // this compiles
return std::unique_ptr<Base>(derived.release()); // and this compiles too
EDIT 1: Używam Visual C++ 2013 jako mojego kompilatora. Oryginalny komunikat o błędzie dla return derived
wygląda następująco:
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>> &&'
EDIT 2: Jest to świeżo utworzona aplikacja konsoli ze standardowej VS 2013 szablonu. Nie zmieniłem ustawień kompilatora. wiersz poleceń kompilator wygląda następująco:
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"
Kompiluje się dobrze z VC++ 2013. Opublikuj MCVE i powiedz nam, jak wywołujesz kompilator. –
@ChristianHackl Dodałem informację o linii poleceń kompilatora do mojego pytania. Nawiasem mówiąc, C++ Shell też się nie kompiluje: http://cpp.sh/8lxwn –
Wciąż nie ma MCVE. http://stackoverflow.com/help/mcve –