2

I have a program with its own smart pointer type derived from std::shared_ptr. The program compiles fine with the latest Visual Studio 2019 v16.11. But trying to build it in GCC or Clang results in error.

After simplification the code where the compilers diverge is as follows:

#include <memory>

template <typename T>
class MyPtr : public std::shared_ptr<T> {
    using base = std::shared_ptr<T>;
public:
    using base::operator=;
    using base::base;
};

int main() {
    MyPtr<int> a = std::make_shared<int>(); //error here
}

GCC emits the error:

conversion from 'std::shared_ptr<int>' to non-scalar type 'MyPtr<int>' requested

Demo: https://gcc.godbolt.org/z/bsxMz96z9

I guess, the program author intent was that

    using base::operator=;
    using base::base;

would add all constructors and assignment operators from std::shared_ptr to MyPtr.

Since both GCC and Clang reject the code, I suspect MSVC is wrong here, but why exactly?

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
Fedor
  • 17,146
  • 13
  • 40
  • 131
  • 4
    I highly doubt that `std::shared_ptr` was designed to be inherited from (the non-virtual [destructor](https://en.cppreference.com/w/cpp/memory/shared_ptr/~shared_ptr) is a good sign of that). And as such I would question any code that did that. Unless you can contact the original author one way or another to ask for clarifications, I would stay far away from such code. – Some programmer dude Sep 25 '21 at 09:02
  • 1
    STL types are not designed to be extended. Most have as said a non-virtual destructor, so deriving from them will result in undefined behavior. So if you want to extend stuff, you need to use aggregation and on your own pointer interface forward what you need to your internal shared_ptr – Pepijn Kramer Sep 25 '21 at 09:10
  • 1
    Normally you would assign a derived class instance to a base class pointer. You're attempting to do it the other way round and that just isn't going to work...... You would need to implement your own factory method that's similar to `std::make_shared` and you wouldn't be able to pass around instances as `std::shared_ptr` anyway due to the lack of virtual destructor. – Den-Jason Sep 25 '21 at 09:15
  • 3
    @P Kramer one may inherit from a class without virtual destructor, as long as he doesn't attempt to delete an object via a ptr to base. – Igor R. Sep 25 '21 at 11:12

0 Answers0