Ionut Alexandru
Ionut Alexandru

Reputation: 806

Is it possible to make shared_ptr covariant?

I tried to make the following example.

struct BaseSPtr{};
struct DerivedSPtr : public BaseSPtr{};


class Base{
    public:
    //virtual shared_ptr<BaseSPtr> function();
    virtual BaseSPtr* function();    
};

class Derived : public Base
{
    public:
    //shared_ptr<DerivedSPtr> function() override;
    DerivedSPtr* function() override;
};

Can someone tell me if is it possible to make the example with shared_ptr valid?

Upvotes: 2

Views: 232

Answers (2)

Marek R
Marek R

Reputation: 37717

Now question is how do you use Derived class?

  • do you use it explicitly and polymorphic call function() is not performed?
  • or do you keep this factory in some storage and function() is called in polymorphic way
  • or do you use this in some templates

In first case just provide function with different name, then you can invoke this function when pointer to derived class is needed.

In second case you should not try convince compiler that you return derived class since polymorphic call will hide this anyway.

In last case just use CRTP as other answer suggested (some call this static polymorphism) and drop virtual keyword.

Upvotes: 0

Jarod42
Jarod42

Reputation: 217293

Unfortunately, no, covariance only applies to pointers and references in C++.

To have similar interface, you have to do something like :

class Base{
public:
    std::shared_ptr<BaseSPtr> function() { return std::shared_ptr<BaseSPtr>(function_v()); }
private:
    virtual BaseSPtr* function_v();
};

class Derived : public Base
{
public:
    std::shared_ptr<DerivedSPtr> function() // Hides Base::function
    {
        return std::shared_ptr<DerivedSPtr>(function_v());
    }
private:
    DerivedSPtr* function_v() override; // Overrides Base::function_v
};

CRTP might help to reduce duplication.

Upvotes: 3

Related Questions