У меня есть функция шаблона в VS2013, предназначенная для выполнения «глубокой копии» любого переданного ей объекта. Одна перегрузка для тривиальных типов просто вызывает оператор =. Но у меня также есть перегрузка, предназначенная для работы с векторами shared_ptr в мои собственные объекты класса Shape, которые можно дублировать только путем вызова функции-члена clone().
struct Shape { virtual std::shared_ptr<Shape> clone() const = 0; };
struct Rectangle : public Shape { virtual std::shared_ptr<Shape> clone() const override; };
Итак, у меня есть эта перегрузка, и компилятор отлично ее выбирает.
template<class SHP>
inline std::vector<std::shared_ptr<SHP>> deep_copy(
const std::vector<std::shared_ptr<SHP>>& val,
typename std::enable_if<std::is_base_of<Shape, SHP>::value>::type** = nullptr)
{
// ... blah blah blah
}
std::vector<std::shared_ptr<Rectangle>> objects;
auto objects2 = deep_copy(objects);
Затем я хотел изменить это, чтобы взять ЛЮБУЮ неключевую коллекцию (например, список) shared_ptr. Хорошо, без проблем, я действительно справился с этим...
template<class COLL>
inline COLL deep_copy(const COLL& val,
typename std::enable_if<std::is_base_of<Shape, typename COLL::value_type::element_type>::value>::type** = nullptr)
Но этот синтаксис не на самом деле гарантирует, что коллекция содержит shared_ptr. Он просто гарантирует, что его value_type имеет вложенный element_type, который является своего рода Shape
Итак, мой вопрос: Каким должен быть синтаксис для обеспечения того, чтобы содержимое коллекции на самом деле было std::shared_ptr чем-то производным от Shape?
Я предпринял несколько попыток сделать это, используя параметры шаблона шаблона, но я все время ошибаюсь.