vendredi 5 février 2021

Overload classes constructor with SFIANE

I am trying to create very basic shared_ptr and want to overload constructor depending on the pointee type.

class A { int a; };
class B :public A {};

    template<typename T>
    class shared_ptr {
    public:
        shared_ptr(T* resource) :pointee_(resource),
            refCount_(new size_t(1))
        {
            std::cout << typeid(resource).name();
            deleter_ = [=]() {delete resource; };
        }

        template<typename U,  typename = std::enable_if_t<std::is_class_v<T>>>
        shared_ptr(U* resource) :pointee_(resource),
            refCount_(new size_t(1))
        {
            std::cout << typeid(resource).name();
            deleter_ = [=]() {delete resource; };
        }


        template<typename X, typename = std::enable_if_t<std::is_integral_v<T>>>
        shared_ptr(X * resource) :pointee_(resource),
            refCount_(new size_t(1))
        {
            std::cout << typeid(resource).name();
            deleter_ = [=]() {delete resource; };
        }
        
        ~shared_ptr()
        {
            --(*refCount_);
            if (!(*refCount_)) {
                deleter_();
            }
        }
    private:
        size_t* refCount_;
        T* pointee_;
        std::function<void()> deleter_;
    };

int main() {
    shared_ptr<A> ptr(new B);
    shared_ptr<int> cptr(new int[3]);
}

So for example I want them to work one way for class types and another for integral.
I am getting a redefinition error:

error C2535: 'playground::shared_ptr<T>::shared_ptr(U *)': member function already defined or declared

Why overload resolution not working with enable_if?
What am I doing wrong?

Aucun commentaire:

Enregistrer un commentaire