Я работаю над реализацией общего указателя. (используя С++ 17, если это имеет значение)
Единственная проблема - конструктор преобразования. Я хочу иметь возможность статического преобразования smart_ptr в smart_ptr базового типа.
template<typename U>
inline smart_ptr(const smart_ptr<U>& rhs)
{
...
}
Это работает, но он также попытается преобразовать smart_ptr в smart_ptr любого другого типа. Например, если у меня есть перегруженная функция, которая может принимать различные виды smart_ptr несвязанного типа, я получаю ошибку компилятора о неоднозначной перегрузке. Итак, мне нужно преобразование из smart_ptr -> smart_ptr только в том случае, если U является производным классом от T.
Похоже, это должно сработать. Он компилируется, но делает наоборот. Это предотвращает работу действительных статических восходящих преобразований, но все же позволяет выполнять приведение к несвязанным типам:
template<typename U>
inline local_shared_ptr(typename enable_if<is_base_of<T,U>::value, const local_shared_ptr<U>&>::type rhs)
{
...
}
РЕДАКТИРОВАТЬ:
Получилось, спасибо за помощь. Я выбираю решение Джарода, так как считаю template <typename U, enable_if_t<is_base_of<T,U>::value, int> = 0>
наиболее лаконичным. Я не знал, что SFINAE может быть таким лаконичным.
Кроме того, поскольку это было упомянуто Натаном:
Как ни странно, одна из проблем, с которыми я столкнулся, заключается в том, что я ожидал вызова конструктора копирования шаблона, когда правая часть имеет тот же тип. По-видимому, компилятор не считает это реализацией конструктора копирования, и вместо этого вызывается автоматически сгенерированный конструктор копирования. Та же проблема для конструктора перемещения и оператора =. Не уверен, что это ошибка MSVC2019.