Я пытаюсь повторить поведение shared_ptr, чтобы лучше понять метапрограммирование шаблонов и type_traits в c ++ 17.В частности, я хочу повторить поведение обновления, то есть шанс назначить / скопировать-создать shared_ptr< Derived >
на shared_ptr< Base >
без явного приведения.
Проверка типа работает, но я получаю ошибку segfaultдля бесконечного цикла в конструкторе копирования, при попытке скопировать или назначить производный объект.
Общий шаблон-класс
#pragma once
#include <memory>
#include <type_traits>
template <typename T>
class Generic {
public:
template <typename DerivedT>
using Assignable = typename std::enable_if<std::is_assignable<T, DerivedT>::value, Generic<T> &>::type;
Generic() : _ptr(nullptr) {}
Generic(T *ptr) : _ptr{ptr} {};
Generic(Generic && cptr) :
_ptr(std::move(cptr._ptr))
{}
Generic(const Generic & cptr) :
_ptr{cptr._ptr}
{}
template <typename DerivedT, typename = Assignable<DerivedT>>
Generic(const Generic<DerivedT> &cptr)
: Generic(static_cast<const Generic &>(cptr)._ptr)
{}
~Generic() = default;
Generic & operator=(Generic && cptr) = default;
Generic & operator=(const Generic & cptr) {
_ptr = cptr._ptr;
return *this;
}
template <typename DerivedT>
Assignable<DerivedT> operator=(const Generic<DerivedT> &cptr) {
_ptr = static_cast<const Generic &>(cptr)._ptr;
return *this;
}
private:
T* _ptr;
};
main.cpp
#include "Generic.hpp"
struct Base {
};
struct Derived : public Base {
};
int main() {
Generic<Derived> derived = Generic<Derived>();
Generic<Base> base(derived);
//Generic<Base> base = derived;
}