Это называется ковариация .
В иерархии классов, когда базовый класс указывает виртуальный метод, который возвращает либо T*
, либо T&
, тогда производные классы могут возвращать U*
или U&
соответственно, при условии, что U
происходит от T
(примечание: и, очевидно, комбинации const
и volatile
).
Это специальное правило, проверенное компилятором, и оно работает, потому что, если U
происходит от T
, тогда U*
может быть приведен к T*
. К сожалению, правило ограничено тем, что оно не работает ни для какого преобразования, и, следовательно, даже если вы обычно можете построить unique_ptr<Shape>
из unique_ptr<Rectangle>
... ковариация не работает.
Вот почему в своей концепции Cloneable Boost предписывает возвращать bare тип указателя. Обидно, но единственный способ получить ковариацию.