Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.5k views
in Technique[技术] by (71.8m points)

c++ - A type that can hold both Foo* and std::shared_ptr<Foo>

What's the most convenient way to be able to store either std::shared_ptr or Foo* in the same type?

Foo* a = ...;
std::shared_ptr<Foo> b = ...;

Bar c = a; // Success, Bar type can hold Foo*
Bar d = b; // Success, Bar type can also hold std::shared_ptr<Foo>

std::variant<Foo*, std::shared_ptr< Foo>> is okay, but it's not possible to dereference it directly and that is kind of annoying. Is there a better way?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Just use a std::shared_ptr<Foo>.

While it is rarely useful, you can in fact construct a non-owning non-counting std::shared_ptr:

auto p = std::shared_ptr<Foo>{std::shared_ptr<void>(), raw_pointer};

If you want to cater to weird people disrespecting the abstraction (looking at the reference-counts, to be specific), you could also stash an eternal anchor somewhere and use that:

struct pass_t {
    template <class... T>
    constexpr int operator()(T&&...) noexcept
    { return 0; }
};
constexpr inline pass_t pass;

inline const std::shared_ptr<void> anchor {nullptr, pass};

auto p = std::shared_ptr<Foo>{anchor, raw_pointer};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...